]> SALOME platform Git repositories - modules/eficas.git/commitdiff
Salome HOME
initial V0
authorsalome <>
Tue, 28 Sep 2004 09:41:16 +0000 (09:41 +0000)
committersalome <>
Tue, 28 Sep 2004 09:41:16 +0000 (09:41 +0000)
32 files changed:
Makefile.in [new file with mode: 0644]
adm_local/unix/config_files/README [new file with mode: 0644]
adm_local/unix/make_commence.in [new file with mode: 0644]
adm_local/unix/make_omniorb.in [new file with mode: 0644]
bin/VERSION [new file with mode: 0755]
build_configure [new file with mode: 0755]
doc/Makefile.in [new file with mode: 0644]
resources/EFICASCatalog.xml [new file with mode: 0644]
resources/EFICAS_en.xml [new file with mode: 0644]
resources/eficas.png [new file with mode: 0644]
resources/eficashomard.png [new file with mode: 0644]
resources/eficaster.png [new file with mode: 0644]
src/EFICASGUI/.param_etude.skel [new file with mode: 0644]
src/EFICASGUI/EFICASGUI.py [new file with mode: 0644]
src/EFICASGUI/EFICAS_icons.po [new file with mode: 0644]
src/EFICASGUI/EFICAS_msg_en.po [new file with mode: 0644]
src/EFICASGUI/Makefile.in [new file with mode: 0644]
src/EFICASGUI/SMESH_utils.py [new file with mode: 0644]
src/EFICASGUI/dataEficas.py [new file with mode: 0644]
src/EFICASGUI/eficasEtude.py [new file with mode: 0644]
src/EFICASGUI/eficasSalome.py [new file with mode: 0644]
src/EFICASGUI/salomedsgui.py [new file with mode: 0644]
src/Makefile.in [new file with mode: 0644]
src/TclQtNotifier/Makefile.in [new file with mode: 0644]
src/TclQtNotifier/moc_notify.refcpp [new file with mode: 0644]
src/TclQtNotifier/notifqtmodule.cpp [new file with mode: 0644]
src/TclQtNotifier/notify.h [new file with mode: 0644]
src/TclQtNotifier/setup.py.in [new file with mode: 0644]
src/patchTkinter/Makefile.in [new file with mode: 0644]
src/patchTkinter/_tkinter.c [new file with mode: 0644]
src/patchTkinter/setup.py.in [new file with mode: 0644]
src/patchTkinter/tkappinit.c [new file with mode: 0644]

diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..8f1fca6
--- /dev/null
@@ -0,0 +1,99 @@
+# -* Makefile *- 
+#
+# Author : Patrick GOLDBRONN (CEA)
+# Date : 28/06/2001
+#
+
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=.
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/bin:@top_srcdir@/resources:./bin:@top_srcdir@/idl
+
+
+@COMMENCE@
+
+SUBDIRS = src 
+
+RESOURCES_FILES = \
+EFICASCatalog.xml \
+EFICAS_en.xml     \
+eficashomard.png  \
+eficas.png       \
+eficaster.png
+
+BIN_SCRIPT= \
+VERSION
+
+# copy header files in common directory
+ifeq ($(HAVE_SSTREAM),yes)
+  include_list=include/salome/SALOMEconfig.h
+else
+  include_list=include/salome/SALOMEconfig.h include/salome/sstream
+endif
+
+#inc: idl $(include_list)
+inc: $(include_list)
+
+include/salome/SALOMEconfig.h: salome_adm/unix/SALOMEconfig.ref
+       -$(RM) $@
+       $(LN_S) ../../$< $@
+
+# test if SALOMEconfig.h has changed (contents)
+salome_adm/unix/SALOMEconfig.ref: salome_adm/unix/SALOMEconfig.h
+       @if ! [ -a $@ ]; then \
+         cp -p $< $@;        \
+       fi;                   \
+       if ! cmp $< $@; then  \
+         cp -p $< $@;        \
+       fi;                   \
+
+include/salome/sstream: salome_adm/unix/sstream
+       -$(RM) $@
+       $(LN_S) ../../$< $@
+
+#depend: depend_idl
+
+#depend_idl:
+#      (cd idl ; $(MAKE) $@) || exit 1
+
+# doc is already build : if you want to had documents, go manually to doc and run 'make doc'
+#doc:
+#      (cd doc && $(MAKE) $@) || exit 1
+
+install-end:
+# finish libtool install
+#      @$(LT) --mode=finish $(libdir)
+
+install-include: $(include_list)
+       $(INSTALL) -d  $(includedir)
+       @for f in X $(include_list); do                         \
+          if test $$f != X; then                               \
+            ($(INSTALL_DATA) $$f $(includedir)/. || exit 1);   \
+          fi;                                                  \
+       done
+
+# install script in $(bindir) :
+install-bin: $(BIN_SCRIPT)
+       $(INSTALL) -d  $(bindir)
+       if test $(BIN_SCRIPT)X != X; then                       \
+               $(INSTALL_PROGRAM) $^ $(bindir);                \
+       fi
+
+#uninstall: uninstall-idl
+
+#uninstall-idl:
+#      $(RM) $(idldir)/*.idl
+
+distclean: distclean-other
+
+distclean-other:
+       -$(RM) salome_adm/unix/*~ salome_adm/unix/*% salome_adm/unix/*.bak salome_adm/unix/*.new salome_adm/unix/*.old
+       -$(RM) salome_adm/unix/make_* 
+       -$(RM) salome_adm/unix/depend salome_adm/unix/SALOMEconfig.h 
+       -$(RM) config.cache config.log config.status 
+
+@MODULE@
+
+install: install-bin install-include install-end
+
diff --git a/adm_local/unix/config_files/README b/adm_local/unix/config_files/README
new file mode 100644 (file)
index 0000000..c9e7d6a
--- /dev/null
@@ -0,0 +1 @@
+this file is needed by cvs to create the directory
\ No newline at end of file
diff --git a/adm_local/unix/make_commence.in b/adm_local/unix/make_commence.in
new file mode 100644 (file)
index 0000000..f6d5ea9
--- /dev/null
@@ -0,0 +1,249 @@
+# common directories to put headerfiles
+inc_builddir=$(top_builddir)/include/salome
+
+@SET_MAKE@
+SHELL=/bin/sh
+
+# header missing
+
+HAVE_SSTREAM=@HAVE_SSTREAM@
+
+
+LIBS=@LIBS@ 
+LDFLAGS=@LDFLAGS@ -L$(top_builddir)/lib/salome -Xlinker -rpath-link -Xlinker -L$(top_builddir)/lib/salome
+# add libstdc++ to link c++ library with libtool !
+LDFLAGS+= -lstdc++
+
+CP=@CP@
+
+# CPP
+
+CPP=@CPP@
+CXXCPP=@CXXCPP@
+CPPFLAGS=@CPPFLAGS@ -I$(inc_builddir) -I$(srcdir) -I.
+
+# C
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+C_DEPEND_FLAG = @C_DEPEND_FLAG@
+
+# C++
+
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ 
+CXX_DEPEND_FLAG = @CXX_DEPEND_FLAG@
+
+# JAVA
+
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_LIBS = @JAVA_LIBS@
+JAVA_LDPATH = @JAVA_LDPATH@
+
+# PYTHON
+
+PYTHON = @PYTHON@
+PYTHONHOME = @PYTHONHOME@
+PYTHON_INCLUDES = @PYTHON_INCLUDES@
+PYTHON_LIBS = @PYTHON_LIBS@
+PYTHON_VERSION = @PYTHON_VERSION@
+PYTHON_SITE = @PYTHON_SITE@
+PYTHON_SITE_INSTALL = @PYTHON_SITE_INSTALL@
+
+# QT
+
+QT_ROOT = @QT_ROOT@
+QT_INCLUDES = @QT_INCLUDES@
+QT_MT_INCLUDES = @QT_INCLUDES@ -DQT_THREAD_SUPPORT
+QT_LIBS = @QT_LIBS@
+QT_MT_LIBS = @QT_MT_LIBS@
+
+MOC = @MOC@
+UIC = @UIC@
+
+
+#QWT
+
+QWT_INCLUDES=@QWT_INCLUDES@
+QWT_LIBS=@QWT_LIBS@
+
+# SIP
+SIP = @SIP@
+SIP_INCLUDES = @SIP_INCLUDES@
+SIP_LIBS = @SIP_LIBS@
+
+# PYQT
+PYQT_SIPS = @PYQT_SIPS@
+PYQT_LIBS = @PYQT_LIBS@
+
+# openGL
+OGL_INCLUDES=@OGL_INCLUDES@
+OGL_LIBS=@OGL_LIBS@
+
+# VTK
+VTK_INCLUDES=@VTK_INCLUDES@
+VTK_LIBS=@VTK_LIBS@
+
+# HDF5
+
+HDF5_INCLUDES=@HDF5_INCLUDES@
+HDF5_LIBS=@HDF5_LIBS@
+HDF5_MT_LIBS=@HDF5_MT_LIBS@
+
+# MED2
+
+MED2_INCLUDES=@MED2_INCLUDES@
+MED2_LIBS=@MED2_LIBS@
+MED2_MT_LIBS=@MED2_MT_LIBS@
+
+# OpenCasCade
+
+OCC_INCLUDES=@CAS_CPPFLAGS@
+OCC_CXXFLAGS=@CAS_CXXFLAGS@
+
+OCC_KERNEL_LIBS=@CAS_KERNEL@
+OCC_OCAF_LIBS=@CAS_OCAF@
+OCC_VIEWER_LIBS=@CAS_VIEWER@
+OCC_MODELER_LIBS=@CAS_MODELER@
+OCC_DATAEXCHANGE_LIBS=@CAS_DATAEXCHANGE@
+OCC_LIBS=@CAS_LDFLAGS@
+
+# MPICH
+
+MPICH_INCLUDES=@MPICH_INCLUDES@
+MPICH_LIBS=@MPICH_LIBS@
+
+# Swig C++ Python
+
+SWIG       = @SWIG@
+SWIG_FLAGS = @SWIG_FLAGS@ -I$(inc_builddir) -I$(srcdir) -I.
+
+# OMNIORB
+
+OMNIORB_ROOT        = @OMNIORB_ROOT@
+OMNIORB_INCLUDES    = @OMNIORB_INCLUDES@
+OMNIORB_LIBS        = @OMNIORB_LIBS@
+OMNIORB_CXXFLAGS    = @OMNIORB_CXXFLAGS@
+
+OMNIORB_IDL         = @OMNIORB_IDL@
+OMNIORB_IDLCXXFLAGS = @OMNIORB_IDLCXXFLAGS@
+OMNIORB_IDLPYFLAGS  = @OMNIORB_IDLPYFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome
+
+OMNIORB_IDL_CLN_H   = @OMNIORB_IDL_CLN_H@
+OMNIORB_IDL_CLN_CXX = @OMNIORB_IDL_CLN_CXX@
+OMNIORB_IDL_CLN_OBJ = @OMNIORB_IDL_CLN_OBJ@
+
+OMNIORB_IDL_SRV_H   = @OMNIORB_IDL_SRV_H@
+OMNIORB_IDL_SRV_CXX = @OMNIORB_IDL_SRV_CXX@
+OMNIORB_IDL_SRV_OBJ = @OMNIORB_IDL_SRV_OBJ@
+
+# Default ORB
+
+CORBA_ROOT        = @CORBA_ROOT@
+CORBA_INCLUDES    = @CORBA_INCLUDES@
+CORBA_LIBS        = @CORBA_LIBS@
+CORBA_CXXFLAGS    = @CORBA_CXXFLAGS@
+
+IDLCXXFLAGS = -bcxx @IDLCXXFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome
+IDLPYFLAGS  = @IDLPYFLAGS@
+
+IDL = @IDL@
+
+IDL_CLN_H   = @IDL_CLN_H@
+IDL_CLN_CXX = @IDL_CLN_CXX@
+IDL_CLN_OBJ = @IDL_CLN_OBJ@
+
+IDL_SRV_H   = @IDL_SRV_H@
+IDL_SRV_CXX = @IDL_SRV_CXX@
+IDL_SRV_OBJ = @IDL_SRV_OBJ@
+
+CPPFLAGS+= $(CORBA_INCLUDES) 
+CXXFLAGS+= $(CORBA_CXXFLAGS)
+
+# add corba libs when link salome application ! 
+#LDFLAGS+= $(CORBA_LIBS)
+LIBS+=$(CORBA_LIBS)
+
+## Shared libraries
+LT_STATIC_EXEC=@LT_STATIC_EXEC@
+DYNAMIC_DIRS=@DYNAMIC_DIRS@
+LT_LIB=libtool
+LT=$(top_builddir)/libtool
+LT_COMPILE=$(LT) --mode=compile $(CC)
+LT_LINK_LIB=$(LT_LIB) --mode=link $(CC) -rpath $(libdir)
+LT_LINK_EXE=$(LT) --mode=link $(CC) $(LT_STATIC_EXEC) -dlopen self -rpath $(bindir) $(DYNAMIC_DIRS)
+LT_RUN=$(LT) --mode=execute
+LT_INSTALL_PROG=$(LT) --mode=install $(INSTALL_PROGRAM)
+LT_INSTALL_LIB=$(LT) --mode=install $(INSTALL_DATA)
+LT_UNINSTALL=$(LT) --mode=uninstall $(RM)
+
+INSTALL=@INSTALL@
+INSTALL_PROGRAM=@INSTALL_PROGRAM@
+INSTALL_DATA=@INSTALL_DATA@
+
+# create a symbolic link (or a copie ?)
+LN_S=@LN_S@
+
+## Installation points
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@/salome
+libdir=@libdir@/salome
+# warning : if user give this path in configure we could have salome/salome :-(
+includedir=@includedir@/salome
+datadir=@datadir@/salome
+idldir=$(prefix)/idl/salome
+sharedpydir=@libdir@/python$(PYTHON_VERSION)/site-packages/salome/shared_modules
+
+docdir=$(datadir)/doc
+
+#
+# begin of package rules
+#
+
+.PHONY: all lib bin inc resources tests install uninstall dep depend depend_idl cleandep mostlyclean clean distclean
+
+.SUFFIXES: .cxx .cc .c .f .o .lo .idl .py .i .ui .po .qm
+
+all:
+       $(MAKE) inc
+       $(MAKE) depend_idl
+       $(MAKE) depend
+       $(MAKE) lib
+       $(MAKE) bin
+       $(MAKE) resources
+
+#
+# add target to build administrative files
+#
+
+Makefile: $(top_builddir)/config.status $(srcdir)/Makefile.in
+       cd $(top_builddir) ; ./config.status
+
+$(top_builddir)/config.status: $(top_srcdir)/configure
+       cd $(top_builddir) ; ./config.status --recheck
+
+# VPATH contain $(srcdir), so make configure is good in top_srcdir and we must add target configure otherwise :-)
+ifneq ($(top_srcdir),$(srcdir))
+configure: $(top_srcdir)/configure
+endif
+
+$(top_srcdir)/configure: $(top_srcdir)/configure.in $(top_srcdir)/aclocal.m4
+       cd $(top_srcdir) ; autoconf
+
+$(top_srcdir)/configure.in: $(top_srcdir)/configure.in.base
+       cd $(top_srcdir) && ./build_configure
+
+
+ACLOCAL_SRC = \
+ac_cxx_bool.m4                    check_corba.m4     check_vtk.m4      \
+ac_cxx_depend_flag.m4             check_hdf5.m4      enable_pthreads.m4        \
+ac_cxx_mutable.m4                 check_mico.m4      libtool.m4                \
+ac_cxx_namespaces.m4              check_omniorb.m4   pyembed.m4                \
+ac_cxx_partial_specialization.m4  check_opengl.m4    python.m4         \
+ac_cxx_typename.m4                check_pthreads.m4  check_cas.m4      \
+ac_cc_warnings.m4                 check_qt.m4        check_med2.m4      \
+check_swig.m4 
+
+$(top_srcdir)/aclocal.m4: $(ACLOCAL_SRC:%=@KERNEL_ROOT_DIR@/salome_adm/unix/config_files/%)
+       cd $(top_srcdir) ; aclocal --acdir=adm_local/unix/config_files -I @KERNEL_ROOT_DIR@/salome_adm/unix/config_files
diff --git a/adm_local/unix/make_omniorb.in b/adm_local/unix/make_omniorb.in
new file mode 100644 (file)
index 0000000..91cfe57
--- /dev/null
@@ -0,0 +1,53 @@
+#=======================================================================
+# Begin specific part to omniorb 
+# (include from file adm/unix/make_omniorb generated by 
+# adm/unix/make_omniorb.in)
+#=======================================================================
+# -* Makefile *- 
+#
+# Author : Patrick GOLDBRONN (CEA)
+# Date : 29/06/2001
+# $Header: /home/salome/PlateFormePAL/Bases_CVS_EDF/Modules_EDF/ASTER_SRC/adm_local/unix/make_omniorb.in,v 1.1.1.1 2003/09/23 17:30:26 salome Exp $
+#
+
+# Client and server object are the same with omniorb
+# There are one header file and one source file generate
+
+#IDLOBJ=$(IDLSRC:%.idl=%$(IDL_CLN_OBJ))
+
+# dependancies between idl and it's generated files
+%$(OMNIORB_IDL_CLN_CXX) %$(OMNIORB_IDL_CLN_H): ${KERNEL_ROOT_DIR}/idl/salome/%.idl
+       $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $<
+
+%$(OMNIORB_IDL_CLN_CXX) %$(OMNIORB_IDL_CLN_H): ${top_srcdir}/idl/%.idl
+       $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $<
+
+# dependncies between idl files
+depend_idl: .depidl
+
+# we use cpp to generate dependencies between idl files.
+# we change cpp output to keep only idl file and transform it to get a suitable rule
+.depidl: $(IDL_FILES)
+       @touch $@
+       @for dep in $? dummy; do \
+         if [ $$dep != "dummy" ]; then \
+           echo Building dependencies for $$dep; \
+           basedep=`basename $$dep .idl`; \
+           header="$$basedep"$(IDL_CLN_H); \
+           sed '\%^'"$$header"':%,\%[^\\]$$%d' <$@ >$@- && mv $@- $@; \
+           $(CPP) $(C_DEPEND_FLAG) -I$(srcdir) $$dep 2>/dev/null | \
+           sed `echo "s%$$basedep\\.idl%$$header:%g"` | \
+           sed 's% $(srcdir)/% %g' | \
+           sed 's% $(top_srcdir)/% %g' | \
+           sed 's% $(top_builddir)/% %g' | \
+           sed 's%^.*:\.o: *%%' | sed 's%^ *\\ *%%'| sed 's%^ *\(.*\):%\1:%' | \
+           sed 's/\.idl/$(IDL_CLN_H)/' >>$@; \
+           echo ''  >>$@; \
+         fi; \
+       done ;
+
+-include .depidl
+
+#=======================================================================
+# End specific part to omniorb 
+#=======================================================================
diff --git a/bin/VERSION b/bin/VERSION
new file mode 100755 (executable)
index 0000000..995a669
--- /dev/null
@@ -0,0 +1 @@
+THIS IS SALOME 2 RNTL - TESTPQT VERSION: 1.1a
diff --git a/build_configure b/build_configure
new file mode 100755 (executable)
index 0000000..e95b0ad
--- /dev/null
@@ -0,0 +1,216 @@
+#!/bin/bash
+
+#
+# Tool for updating list of .in file for the SALOME project 
+# and regenerating configure script
+#
+# Author : Marc Tajchman - CEA
+# Date : 10/10/2002
+# $Header $
+#
+
+ORIG_DIR=`pwd`
+CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"`
+
+########################################################################
+# Test if the KERNEL_ROOT_DIR is set correctly
+
+if test ! -d "${KERNEL_ROOT_DIR}"; then
+    echo "failed : KERNEL_ROOT_DIR variable is not correct !"
+    exit
+fi
+
+# Test if the KERNEL_SRC is set correctly
+
+#if test ! -d "${KERNEL_SRC}"; then
+#    echo "failed : KERNEL_SRC variable is not correct !"
+#    exit
+#fi
+########################################################################
+# find_in - utility function
+#
+# usage :  
+#    find_in directory filename 
+#
+# Finds files following the *.in pattern, recursively in the
+# directory (first argument).
+# Results are appended into the file (second argument)
+#
+# Difference from the standard unix find is that files are tested
+# before directories
+# 
+
+find_in()
+{
+  local i
+  local f=$2
+
+# if the first argument is not a directory, returns
+
+  if [ ! -d "$1" ] ; then 
+     return 
+  fi
+
+# dont look in the CVS directories
+
+  case $1 in
+    */CVS) return ;;
+    *) ;;
+  esac
+
+# for each regular file contained in the directory
+# test if it's a .in file
+
+  for i in "$1"/*
+  do
+     if [ -f "$i" ] ; then
+       case $i in 
+         *.in) echo "  "$i" \\" >> $f;;
+         *) ;;
+        esac
+     fi
+  done
+
+# for each subdirectory of the first argument, proceeds recursively
+
+  for i in "$1"/*
+  do
+     if [ -d "$i" ] ; then
+        find_in "$i" "$f"
+     fi
+  done
+}
+
+
+#######################################################################
+# Generate list of .in files (Makefile.in, config.h.in, etc)
+# appending it in file configure.in
+
+cd ${CONF_DIR}
+ABS_CONF_DIR=`pwd`
+
+#
+# Common part of the configure.in file
+#
+chmod u+w configure.in.base
+if ! \cp -f configure.in.base configure.in_tmp1 
+then
+       echo
+       echo "error : can't create files in" ${CONF_DIR}
+       echo "aborting ..."
+        chmod u-w configure.in.base 
+       exit
+fi
+chmod u-w configure.in.base 
+
+if [ -e "${CONF_DIR}/salome_adm" ] ; then
+    \rm -f ${CONF_DIR}/salome_adm
+fi
+
+# make a link allowing AC_OUTPUT to find the salome_adm/.../*.in  files
+echo "" >> configure.in_tmp1
+echo 'ln -fs ${KERNEL_ROOT_DIR}/salome_adm ${ROOT_SRCDIR}' >> configure.in_tmp1
+
+echo  "" >> configure.in_tmp1
+echo "AC_OUTPUT([ \\" >> configure.in_tmp1
+
+#
+# List of .in files in the adm/unix directory
+# These files MUST be on top of AC_OUTPUT list so we
+# put them "manually"
+#
+
+echo " ./salome_adm/unix/SALOMEconfig.h \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/F77config.h \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/sstream \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/depend \\" >> configure.in_tmp1
+#echo "        ./salome_adm/unix/make_omniorb \\" >> configure.in_tmp1
+echo " ./adm_local/unix/make_omniorb \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/envScript \\" >> configure.in_tmp1
+#echo "        ./salome_adm/unix/make_commence \\" >> configure.in_tmp1
+echo " ./adm_local/unix/make_commence \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/make_conclude \\" >> configure.in_tmp1
+#echo "        ./adm_local/unix/make_conclude \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/make_module \\" >> configure.in_tmp1
+
+\rm -f configure.in_tmp2
+touch configure.in_tmp2
+find_in . configure.in_tmp2
+
+sed -e '/^     .\/salome_adm/d'    \
+    -e '/configure.in/d'      \
+    -e '/^     .\/adm_local/d'   \
+    -e 's/.in / /'            \
+    configure.in_tmp2  >>  configure.in_tmp1
+
+echo  "])" >> configure.in_tmp1
+
+# delete the link created for AC_OUTPUT
+echo "" >> configure.in_tmp1
+#echo 'rm -f ${ROOT_SRCDIR}/salome_adm' >> configure.in_tmp1
+\mv configure.in_tmp1 configure.in_new
+\rm  -f configure.in_tmp2 
+
+
+########################################################################
+# Create new (or replace old) configure.in file
+# Print a message if the file is write protected
+#
+
+echo
+if test ! -f configure.in
+then
+       echo -n "Creating new file 'configure.in' ... "
+       if \mv configure.in_new configure.in >& /dev/null
+       then
+               echo "done"
+       else
+               echo "error, check your file permissions"
+       fi
+else
+       echo -n "Updating 'configure.in' file ... "
+       if ! \cp configure.in configure.in_old >& /dev/null
+       then
+               echo
+               echo
+               echo "Can't backup previous configure.in"
+               echo -n "Continue (you will not be able to revert) - (Y/N) ? "
+               read R
+                case "x$R" in
+                   xn*) exit;;
+                   xN*) exit;;
+               esac
+               echo
+               echo -n "                                 "
+       fi
+       if \cp configure.in_new configure.in >& /dev/null
+       then
+               echo "done"
+       else
+               echo
+               echo "error, can't update previous configure.in"
+       fi
+fi
+
+########################################################################
+# Use autoconf to rebuild the configure script
+#
+
+if test -f configure
+then
+       echo -n "Updating 'configure' script ...  "
+else
+       echo -n "Creating 'configure' script ...  "
+fi
+
+aclocal --acdir=adm_local/unix/config_files -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files
+if autoconf
+then
+       echo "done"
+else
+       echo "failed (check file permissions and/or user quotas ...)"
+fi
+
+cd ${ORIG_DIR}
+
+echo
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644 (file)
index 0000000..069960a
--- /dev/null
@@ -0,0 +1,32 @@
+
+# -* Makefile *- 
+#
+# Author : Patrick GOLDBRONN (CEA)
+# Date : 30/11/2001
+#
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=..
+srcdir=@srcdir@
+VPATH=.:@srcdir@
+
+SUBDIRS=
+
+doc:
+       @@SETX@; for d in $(SUBDIRS); do        \
+          (cd $$d && $(MAKE) $@) || exit 1;    \
+       done
+clean:
+       @@SETX@; for d in $(SUBDIRS); do        \
+          (cd $$d && $(MAKE) $@) || exit 1;    \
+       done
+
+distclean: clean
+       @@SETX@; for d in $(SUBDIRS); do        \
+          (cd $$d && $(MAKE) $@) || exit 1;    \
+       done
+
+install:
+       @@SETX@; for d in $(SUBDIRS); do        \
+          (cd $$d && $(MAKE) $@) || exit 1;    \
+       done
diff --git a/resources/EFICASCatalog.xml b/resources/EFICASCatalog.xml
new file mode 100644 (file)
index 0000000..2568f66
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version='1.0' encoding='us-ascii' ?>
+<!-- XML component catalog -->
+<begin-catalog>
+
+<!-- Path prefix information -->
+
+<path-prefix-list>
+</path-prefix-list>
+
+<!-- Component list -->
+<component-list>
+        <component>
+                <!-- Component identification -->
+                <component-name>EFICAS</component-name>
+                <component-username>EFICAS GUI</component-username>
+                <component-type>Data</component-type>
+                <component-author>P.RASCLE</component-author>
+                <component-version> 1.0</component-version>
+                <component-comment>EDF - RD</component-comment>
+                <component-multistudy>1</component-multistudy>
+                <component-icone>eficas.png</component-icone>
+                <constraint>'linux' ~ OS</constraint>
+        </component>
+</component-list>
+</begin-catalog>
diff --git a/resources/EFICAS_en.xml b/resources/EFICAS_en.xml
new file mode 100644 (file)
index 0000000..617dac7
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version='1.0' encoding='us-ascii'?>
+<!DOCTYPE application PUBLIC "" "desktop.dtd">
+
+<!--  GUI customization for EFICAS component  -->
+
+<application
+            title="EFICAS component"
+            date="9/12/2001"
+            author="Paul RASCLE"
+            appId="EFICAS" >
+
+  <desktop>
+
+  <!-- ### MENUBAR ###  -->
+
+    <menubar>
+      <menu-item label-id="EFICAS" item-id="90" pos-id="3">
+        <popup-item item-id="941" label-id="Eficas pour ASTER" icon-id="eficaster.png" tooltip-id="Editer un jeu de commande ASTER avec Eficas" accel-id="" toggle-id="" execute-action=""/>
+        <popup-item item-id="946" label-id="Eficas pour Homard" icon-id="eficashomard.png" tooltip-id="Editer un jeu de commande HOMARD avec Eficas" accel-id="" toggle-id="" execute-action=""/>
+      </menu-item>
+    </menubar>
+
+  <!-- ### TOOLBAR ###  -->
+
+    <toolbar label-id="Eficas">
+        <toolbutton-item item-id="4041" label-id="Eficas" icon-id="eficaster.png" tooltip-id="Editer un jeu de commande ASTER avec Eficas" accel-id="" toggle-id="" execute-action=""/>
+        <toolbutton-item item-id="4046" label-id="Eficas pour Homard" icon-id="eficaster.png" tooltip-id="Editer un jeu de commande HOMARD avec Eficas" accel-id="" toggle-id="" execute-action=""/>
+    </toolbar>
+
+  </desktop>   
+</application>
diff --git a/resources/eficas.png b/resources/eficas.png
new file mode 100644 (file)
index 0000000..081f72e
Binary files /dev/null and b/resources/eficas.png differ
diff --git a/resources/eficashomard.png b/resources/eficashomard.png
new file mode 100644 (file)
index 0000000..8df8f60
Binary files /dev/null and b/resources/eficashomard.png differ
diff --git a/resources/eficaster.png b/resources/eficaster.png
new file mode 100644 (file)
index 0000000..8ceb9f9
Binary files /dev/null and b/resources/eficaster.png differ
diff --git a/src/EFICASGUI/.param_etude.skel b/src/EFICASGUI/.param_etude.skel
new file mode 100644 (file)
index 0000000..d7367e2
--- /dev/null
@@ -0,0 +1,13 @@
+# Fichier adlv100a.para : regroupe les paramètres d'exécution de l'étude
+
+masterdir = "%(REP_ETUDE)s"
+etude = "%(ETUDE)s"
+prof_etd = (
+("comm","%(COMMAND_FILE_NAME)s","%(LOCAL_USER)s","%(LOCAL_MACHINE)s","1.i","D"),
+("med","%(MESH_FILE_NAME)s","%(LOCAL_USER)s","%(LOCAL_MACHINE)s","21","D"),
+("resu","%(REP_ETUDE)s/%(ETUDE)s.resu","%(LOCAL_USER)s","%(LOCAL_MACHINE)s","8","R"),
+("med","%(REP_ETUDE)s/%(ETUDE)s.med","%(LOCAL_USER)s","%(LOCAL_MACHINE)s","80","R"),
+("mess","%(REP_ETUDE)s/%(ETUDE)s.mess","%(LOCAL_USER)s","%(LOCAL_MACHINE)s","6","R"),
+("unv","%(REP_ETUDE)s/%(ETUDE)s.unv","%(LOCAL_USER)s","%(LOCAL_MACHINE)s","30","R"),
+("base","%(REP_ETUDE)s/%(ETUDE)s.base","%(LOCAL_USER)s","%(LOCAL_MACHINE)s","40","R"),
+)
diff --git a/src/EFICASGUI/EFICASGUI.py b/src/EFICASGUI/EFICASGUI.py
new file mode 100644 (file)
index 0000000..59852ca
--- /dev/null
@@ -0,0 +1,104 @@
+"""
+    Interface PyQt
+"""
+import qt
+import libSALOME_Swig
+import SalomePyQt
+
+# Variable globale pour stocker le Workspace de Salome
+
+WORKSPACE=None
+studyId=None
+
+# -----------------------------------------------------------------------------
+
+import notifqt
+#import Tkinter
+#root=Tkinter.Tk()
+#root.withdraw()
+
+def g():
+   print "lastWindowClosed()"
+   root.destroy()
+
+qt.QObject.connect(qt.qApp,qt.SIGNAL("lastWindowClosed()"),g)
+
+# -----------------------------------------------------------------------------
+
+import salome
+
+sg=salome.SalomeGUI()
+sgPyQt=SalomePyQt.SalomePyQt()
+print "EFicasGUI :: :::::::::::::::::::::::::::::::::::::::::::::::::::::"
+
+# -----------------------------------------------------------------------------
+
+def setWorkSpace(workSpace):
+   print "EficasGUI --- setWorkSpace"
+   global WORKSPACE
+   print workSpace
+   WORKSPACE=workSpace
+   print "WORKSPACE: ",WORKSPACE
+   # le desktop
+   d=sgPyQt.getDesktop()
+
+   # creation d'une message box
+   #qt.QMessageBox.information(d,"titre","message")
+
+   # recuperation du workspace
+   ws=sgPyQt.getMainFrame()
+   print ws
+
+# -----------------------------------------------------------------------------
+
+def OnGUIEvent(commandID) :
+   print "EficasGUI :: OnGUIEvent :::::::::::::::::::::::::::::::::commandID,WORKSPACE = ",commandID,WORKSPACE
+   if dict_command.has_key(commandID):
+      print "OnGUIEvent ::::::::::  commande associée  : ",commandID      
+      dict_command[commandID](WORKSPACE)
+   else:
+      print "Pas de commande associée a : ",commandID
+
+# -----------------------------------------------------------------------------
+
+def setSettings():
+   print "setSettings"
+   print sgPyQt.getStudyId()
+
+# -----------------------------------------------------------------------------
+
+def activeStudyChanged(ID):
+   global studyId
+   # ne marche pas car sg est supposé résider dans une etude
+   # studyId=sg.getActiveStudyId()
+   studyId=ID
+   print "studyId: ",sg.getActiveStudyId()
+   print "On a changé d'étude active",studyId
+   print sgPyQt.getStudyId()
+
+
+# -----------------------------------------------------------------------------
+
+import eficasSalome
+
+def runEficas(ws):
+   print "runEficas"
+   eficasSalome.runEficas(ws,"ASTER")
+   
+def runEficaspourHomard(ws):
+   print "runEficas"
+   eficasSalome.runEficas(ws,"HOMARD")
+    
+def runEficasHomard():
+   print "runEficas"
+   eficasSalome.runEficas(None,"HOMARD")
+
+# Partie applicative
+
+dict_command={
+               941:runEficas,
+               946:runEficaspourHomard,
+               4041:runEficas,
+               4046:runEficaspourHomard,
+             }
+
diff --git a/src/EFICASGUI/EFICAS_icons.po b/src/EFICASGUI/EFICAS_icons.po
new file mode 100644 (file)
index 0000000..b386757
--- /dev/null
@@ -0,0 +1,11 @@
+# This is a Qt message file in .po format.  Each msgid starts with
+# a scope.  This scope should *NOT* be translated - eg. "Foo::Bar"
+# would be translated to "Pub", not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n"
+"PO-Revision-Date: YYYY-MM-DD\n"
+"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
diff --git a/src/EFICASGUI/EFICAS_msg_en.po b/src/EFICASGUI/EFICAS_msg_en.po
new file mode 100644 (file)
index 0000000..b386757
--- /dev/null
@@ -0,0 +1,11 @@
+# This is a Qt message file in .po format.  Each msgid starts with
+# a scope.  This scope should *NOT* be translated - eg. "Foo::Bar"
+# would be translated to "Pub", not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n"
+"PO-Revision-Date: YYYY-MM-DD\n"
+"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
diff --git a/src/EFICASGUI/Makefile.in b/src/EFICASGUI/Makefile.in
new file mode 100644 (file)
index 0000000..b4a1bc6
--- /dev/null
@@ -0,0 +1,55 @@
+#==============================================================================
+#  File      : Makefile.in
+#  Created   : dim déc  9 18:35:11 CET 2001
+#  Author    : Paul RASCLE, EDF
+#  Project   : SALOME
+#  Copyright : EDF 2001
+#==============================================================================
+
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome
+
+
+@COMMENCE@
+
+# header files 
+EXPORT_HEADERS=
+
+
+# Libraries targets
+
+LIB = 
+LIB_SRC = 
+
+LIB_CLIENT_IDL =
+
+LIB_SERVER_IDL = 
+
+# .po files to transform in .qm
+PO_FILES =  EFICAS_msg_en.po EFICAS_icons.po
+
+EXPORT_PYSCRIPTS = \
+dataEficas.py  \
+eficasEtude.py \
+EFICASGUI.py   \
+salomedsgui.py \
+SMESH_utils.py \
+eficasSalome.py  
+
+PYUIC = pyuic
+
+%.py:%.ui
+       $(PYUIC) $< -o $@
+
+# additionnal information to compil and link file
+
+CPPFLAGS += $(QT_INCLUDES) $(VTK_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) $(SIP_INCLUDES)
+CPPFLAGS += -I$(top_builddir)/SALOME/src/SALOME_PYQT
+CXXFLAGS += 
+
+LDFLAGS += $(PYTHON_LIBS) $(PYQT_LIBS) -lSalomeGUI 
+
+@CONCLUDE@
diff --git a/src/EFICASGUI/SMESH_utils.py b/src/EFICASGUI/SMESH_utils.py
new file mode 100644 (file)
index 0000000..d9c097d
--- /dev/null
@@ -0,0 +1,164 @@
+#=============================================================================
+# File      : SMESH_utils.py
+# Created   : jeu fév 20 18:53:34 CET 2003
+# Author    : Paul RASCLE, EDF
+# Project   : SALOME
+# Copyright : EDF 2003
+#  $Header: /home/salome/PlateFormePAL/Bases_CVS_EDF/Modules_EDF/ASTER_SRC/src/ASTER/SMESH_utils.py,v 1.1.1.1.2.1 2004/05/18 11:40:20 salome Exp $
+#=============================================================================
+
+from omniORB import CORBA
+import LifeCycleCORBA
+import SALOMEDS
+import GEOM
+import SMESH
+
+# initialise the ORB
+orb = CORBA.ORB_init([''], CORBA.ORB_ID)
+
+# create an LifeCycleCORBA instance
+lcc = LifeCycleCORBA.LifeCycleCORBA(orb)
+
+geom = lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+smesh = lcc.FindOrLoadComponent("FactoryServer", "SMESH")
+
+    #--------------------------------------------------------------------------
+
+def entryToIor(myStudy,entry):
+    myBuilder = myStudy.NewBuilder()
+    ior = None
+    SO = None
+    try:
+        SO = myStudy.FindObjectID(entry)
+    except:
+        print "invalid entry: ",entry
+        SO = None
+    if SO != None:
+        boo,iorso = myBuilder.FindAttribute(SO,"AttributeIOR")
+        if boo == 0:
+            print "no IOR attribute on study object: ", entry
+        else:
+            iorString = iorso.Value()
+            print iorString
+            ior = orb.string_to_object(iorString)
+    return ior
+
+    #--------------------------------------------------------------------------
+
+def entryToName2(myStudy,entry):
+    myBuilder = myStudy.NewBuilder()
+    name =[] 
+    SO = None
+    try:
+            SO = myStudy.FindObjectID(entry)
+    except:
+            print "invalid entry: ",entry
+            SO = None
+    if SO != None:
+            boo,nameso = myBuilder.FindAttribute(SO,"AttributeName")
+            if boo == 0:
+                print "no Name attribute on study object: ", entry
+            else:
+                name.append(nameso.Value())
+    return name
+
+def entryToName(myStudy,entryList):
+    myBuilder = myStudy.NewBuilder()
+    name =[]
+    SO = None
+    for entry in entryList:
+        try:
+            SO = myStudy.FindObjectID(entry)
+        except:
+            print "invalid entry: ",entry
+            SO = None
+        if SO != None:
+            boo,nameso = myBuilder.FindAttribute(SO,"AttributeName")
+            if boo == 0:
+                print "no Name attribute on study object: ", entry
+            else:
+                name.append(nameso.Value())
+    return name
+
+
+    #--------------------------------------------------------------------------
+
+def getMainShape(myStudy,entry):
+    anObject=entryToIor(myStudy,entry)
+    subShape=anObject._narrow(GEOM.GEOM_Shape)
+    if subShape == None:
+        print "entry does not give a shape: ", entry
+        return None
+    isMain=subShape._get_IsMainShape()
+    if isMain:
+        iorMain=subShape
+    else:
+        iorStringMain=subShape._get_MainName()
+        iorMain = orb.string_to_object(iorStringMain)
+    return iorMain
+        
+
+def getMainShapeName(myStudy,entry):
+    anObject=entryToIor(myStudy,entry)
+    subShape=anObject._narrow(GEOM.GEOM_Shape)
+    if subShape == None:
+        print "entry does not give a shape: ", entry
+        return None
+    isMain=subShape._get_IsMainShape()
+    if isMain:
+        iorMain=subShape
+    else:
+        iorStringMain=subShape._get_MainName()
+        iorMain = orb.string_to_object(iorStringMain)
+    stringior=  orb.object_to_string(iorMain)
+    return stringior
+    #--------------------------------------------------------------------------
+
+def getSMESHSubShapeIndexes(myStudy, entryList, typenoeudorcell = 0):
+    # typenoeudorcell = 0 on traite des noeuds
+    # typenoeudorcell = 1 on traite des faces
+    refList = []
+    subShapeIndexes = []
+    if len(entryList) > 0:
+        iorMain = getMainShapeName(myStudy, entryList[0])
+
+    myCL=smesh.GetOrCreateCL(str(iorMain))
+
+    if len(entryList) > 0:
+         for idShape in entryList:
+             print "idShape"
+             print idShape
+             refShape = entryToName2(myStudy,idShape)
+             if refShape != None:
+                  for Shape in refShape:
+                      refList.append(Shape)
+             IORShape = entryToIor(myStudy,idShape)
+             myCL.SetIdAsCL(orb.object_to_string(IORShape),typenoeudorcell)
+            
+    studyId = myStudy._get_StudyId()
+    return refList
+
+    #--------------------------------------------------------------------------
+
+def getAsterGroupNo(myStudy,entryList):
+    typenoeudorcell = 0
+    subShapeIndexes = getSMESHSubShapeIndexes(myStudy, entryList,typenoeudorcell)
+    labelGroupNo = []
+    for val in subShapeIndexes:
+        labelGroupNo.append(val)
+    return labelGroupNo
+
+    #--------------------------------------------------------------------------
+
+def getAsterGroupMa(myStudy,entryList):
+    typenoeudorcell = 1
+    subShapeIndexes = getSMESHSubShapeIndexes(myStudy, entryList,typenoeudorcell)
+    labelGroupMa = []
+    for val in subShapeIndexes:
+        #label="GMM%d"%(val)
+        labelGroupMa.append(val)
+    print labelGroupMa
+    return labelGroupMa
+
+    #--------------------------------------------------------------------------
+
diff --git a/src/EFICASGUI/dataEficas.py b/src/EFICASGUI/dataEficas.py
new file mode 100644 (file)
index 0000000..9450b9a
--- /dev/null
@@ -0,0 +1,36 @@
+import sys,os
+
+eficas_root=os.environ["EFICAS_ROOT"]
+
+sys.path[:0]=[os.path.join(eficas_root,'Aster'),
+              os.path.join(eficas_root,'Homard'),
+              eficas_root,
+              os.path.join(eficas_root,'Editeur'),
+             ]
+
+# Modules Python
+import Tkinter
+
+# Modules Eficas
+import import_code
+import splash
+
+
+def init(top,code="ASTER"):
+    splash.init_splash(top,code=code,titre="Lancement d'EFICAS pour %s" %code)
+    splash._splash.configure(text="Chargement d'EFICAS en cours.\n Veuillez patienter ...")
+    # Enregistrement dans l étude
+    import eficasEtude
+    MaRef=eficasEtude.Eficas_In_Study()
+
+    import eficas
+    class MyEficas(eficas.EFICAS):
+        def quit(self):
+            eficas.EFICAS.quit(self)
+            self.top.destroy()
+        
+        def contexte(self):
+            self.salome=MaRef
+
+    moi=MyEficas(top,code=code)
+    moi.contexte()
diff --git a/src/EFICASGUI/eficasEtude.py b/src/EFICASGUI/eficasEtude.py
new file mode 100644 (file)
index 0000000..c2a9d39
--- /dev/null
@@ -0,0 +1,52 @@
+#=============================================================================
+# File      : EficasEtude.py
+# Created   : mar fév 25 09:48:34 CET 2003
+# Author    : Pascale NOYRET, EDF
+# Project   : SALOME
+# Copyright : EDF 2003
+#  $Header: /home/salome/PlateFormePAL/Bases_CVS_EDF/Modules_EDF/ASTER_SRC/src/ASTERGUI/eficasEtude.py,v 1.1.1.1.2.1 2004/05/18 11:40:21 salome Exp $
+#=============================================================================
+
+import salome
+import re
+from tkFileDialog import asksaveasfilename
+
+import salomedsgui
+aGuiDS=salomedsgui.guiDS()
+
+#--------------------------------------------------------------------------
+
+class Eficas_In_Study:
+
+      def __init__(self):
+          import SMESH_utils
+          self.enregistre()
+          self.liste_deja_la=[]
+          
+      def  enregistre(self):
+           self.fatherId=aGuiDS.enregistre("Eficas")
+           salome.sg.updateObjBrowser(0)
+
+      def  rangeInStudy(self,fichier):
+          if fichier not in self.liste_deja_la :
+               self.liste_deja_la.append(fichier)
+                Nom=re.split("/",fichier)[-1]
+
+                self.commId=aGuiDS.createItemInStudy(self.fatherId,Nom)
+                aGuiDS.setExternalFileAttribute(self.commId,"FICHIER_EFICAS",fichier)
+                salome.sg.updateObjBrowser(0)
+
+      def creeConfigTxt(self,fichier,dico):
+           sauvegarde = asksaveasfilename(title="fichier config.txt",
+                                     defaultextension='.txt',
+                                     initialdir = fichier)
+           f=open(sauvegarde,'w+')
+           for unite in dico.keys():
+                print unite
+                type=dico[unite][0]
+                fic=dico[unite][1:]
+                ligne="fort."+str(unite)+" "+type+" "+fic
+                f.write(ligne)
+           f.close()
+           self.rangeInStudy(sauvegarde)
+           
diff --git a/src/EFICASGUI/eficasSalome.py b/src/EFICASGUI/eficasSalome.py
new file mode 100644 (file)
index 0000000..964a706
--- /dev/null
@@ -0,0 +1,43 @@
+import qt
+import notifqt
+# -----------------------------------------------------------------------------
+import sys
+
+# Remplacement de la fonction exit standard par une fonction
+# qui n'interrompt pas l'execution
+sys._exit=sys.exit
+
+def exit(ier):
+   print "appel de exit: ",ier
+
+sys.exit=exit
+# Fin remplacement
+
+initialised=0
+import Tkinter
+root=Tkinter.Tk()
+root.withdraw()
+
+
+def runEficas(ws,code="ASTER"):
+    global initialised
+    if not initialised:
+        t=Tkinter.Toplevel()
+        t.withdraw()
+        print t.geometry()
+        print t.winfo_geometry()
+        import dataEficas; dataEficas.init(t,code)
+        t.update()
+        print t.geometry()
+        print t.winfo_geometry()
+        t.deiconify()
+        t.update()
+
+        #initialised=1
+
+def runHomard() :
+    runEficas(None,"HOMARD")
+
+def runAster() :
+    runEficas(None,"ASTER")
+
diff --git a/src/EFICASGUI/salomedsgui.py b/src/EFICASGUI/salomedsgui.py
new file mode 100644 (file)
index 0000000..d30549c
--- /dev/null
@@ -0,0 +1,154 @@
+#  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+# 
+#  This library is free software; you can redistribute it and/or 
+#  modify it under the terms of the GNU Lesser General Public 
+#  License as published by the Free Software Foundation; either 
+#  version 2.1 of the License. 
+# 
+#  This library is distributed in the hope that it will be useful, 
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#  Lesser General Public License for more details. 
+# 
+#  You should have received a copy of the GNU Lesser General Public 
+#  License along with this library; if not, write to the Free Software 
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+#
+#
+#
+#  File   : salomedsgui.py
+#  Author : Paul RASCLE, EDF
+#  Module : KERNEL
+#
+#--------------------------------------------------------------------------
+
+import salome
+import SALOMEDS
+import string,os
+
+class guiDS:
+    """
+    Study (SALOMEDS) interface from python gui (ex: IAPP embedded PyQt GUI)
+    """
+    _myStudyManager = None
+    _myStudy = None
+    _myBuilder = None
+    _father = None
+    _component = None
+
+    def __init__(self):
+        self._myStudyManager = salome.myStudyManager
+        self._myStudy = salome.myStudy
+        self._myBuilder = self._myStudy.NewBuilder()
+
+    def enregistre(self,myModule):
+        if self._father is None:
+            father = self._myStudy.FindComponent(myModule)
+            if father is None:
+                father = self._myBuilder.NewComponent(myModule)
+                A1 = self._myBuilder.FindOrCreateAttribute(father,"AttributeName")
+                FName = A1._narrow(SALOMEDS.AttributeName)
+                FName.SetValue(myModule)
+            self._father   = father
+            self._component = myModule
+        return self._father.GetID()
+
+    def createItemInStudy(self,fatherId,objectName):
+        objId = None
+        if self._component is not None:
+            listSO = self._myStudy.FindObjectByName(objectName,self._component)
+            if len(listSO) == 0:
+                father = self._myStudy.FindObjectID(fatherId)
+                newObj = self._myBuilder.NewObject(father)
+                A1= self._myBuilder.FindOrCreateAttribute(newObj,"AttributeName")
+                FName = A1._narrow(SALOMEDS.AttributeName)
+                FName.SetValue(objectName)
+                objId = newObj.GetID()
+        return objId
+
+    def getReference(self,objectId):
+        mySO = self._myStudy.FindObjectID(objectId)
+        boo,RefSO = mySO.ReferencedObject()
+        if boo:
+            objectId=RefSO.GetID()
+        return objectId        
+
+    def addReference(self,fatherId,refId):
+        father = self._myStudy.FindObjectID(fatherId)
+        ref = self._myStudy.FindObjectID(refId)
+        newObj = self._myBuilder.NewObject(father)
+       A1 =  self._myBuilder.FindOrCreateAttribute(ref,"AttributeName")
+       FName = A1._narrow(SALOMEDS.AttributeName)
+       Name_ref = FName.Value()
+       path_father , none = string.split(self._myStudy.GetObjectPath(ref),Name_ref)
+       path_father , none = os.path.split(path_father)
+       #print "salomedsgui::addReference : path_father_ref = ",path_father
+       #print "salomedsgui::addReference : Path_father = ",self._myStudy.GetObjectPath(father)
+       if self._myStudy.GetObjectPath(father) != path_father :
+            self._myBuilder.Addreference(newObj,ref)
+
+    def setExternalFileAttribute(self,objectId,filetype,filename):
+        mySO = self._myStudy.FindObjectID(objectId)
+        A1 = self._myBuilder.FindOrCreateAttribute(mySO,"AttributeExternalFileDef")
+        AFileName = A1._narrow(SALOMEDS.AttributeExternalFileDef)
+        AFileName.SetValue(filename)
+        print filename
+        A2 = self._myBuilder.FindOrCreateAttribute(mySO,"AttributeFileType")
+        AFileType = A2._narrow(SALOMEDS.AttributeFileType)
+        print filetype
+        AFileType.SetValue(filetype)
+        print filetype
+                          
+    def getExternalFileAttribute(self,filetype, objectId):
+        print filetype
+        print objectId
+        mySO = self._myStudy.FindObjectID(objectId)
+        boo,RefSO = mySO.ReferencedObject()
+        if boo:
+            print RefSO
+            mySO = RefSO
+        print mySO
+        val=""
+        boo,attr =  self._myBuilder.FindAttribute(mySO,"AttributeFileType")
+        print "AttributeFileType ",boo
+        if boo:
+            boo=0
+            val=attr.Value()
+            print val
+        if val==filetype:
+            boo,attr =  self._myBuilder.FindAttribute(mySO,"AttributeExternalFileDef")
+        val=""
+        if boo: 
+             val=attr.Value()
+        attribute=val
+        return (boo,attribute)
+
+    def getNameAttribute(self, objectId):
+        mySO = self._myStudy.FindObjectID(objectId)
+        boo,RefSO = mySO.ReferencedObject()
+        if boo:
+            mySO = RefSO
+        boo,attr =  self._myBuilder.FindAttribute(mySO,"AttributeName")
+        val=""
+        if boo:
+            val=attr.Value()
+            print val
+        return val
+            
+            
+    def getChildren(self, objectId):
+        children=[]
+        mySO = self._myStudy.FindObjectID(objectId)
+        boo,RefSO = mySO.ReferencedObject()
+        if boo:
+            mySO = RefSO
+        it = self._myStudy.NewChildIterator(mySO)
+        while it.More():
+            CSO = it.Value()
+            children.append(CSO.GetID())
+            it.Next()
+        print children
+        return children
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644 (file)
index 0000000..4694a72
--- /dev/null
@@ -0,0 +1,20 @@
+#==============================================================================
+#  File      : Makefile.in
+#  Created   : ven déc  7 13:32:20 CET 2001
+#  Author    : Paul RASCLE, EDF
+#  Project   : SALOME
+#  Copyright : EDF 2001
+#  $Header: /home/salome/PlateFormePAL/Bases_CVS_EDF/Modules_EDF/ASTER_SRC/src/Makefile.in,v 1.3.2.1 2004/06/07 17:40:26 salome Exp $
+#==============================================================================
+
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=..
+srcdir=@srcdir@
+VPATH=.:@srcdir@
+
+@COMMENCE@
+
+SUBDIRS = TclQtNotifier EFICASGUI 
+
+@MODULE@
diff --git a/src/TclQtNotifier/Makefile.in b/src/TclQtNotifier/Makefile.in
new file mode 100644 (file)
index 0000000..c85d71d
--- /dev/null
@@ -0,0 +1,48 @@
+# -* Makefile *- 
+#
+# Author : Nicolas REJNERI
+# Date   : Sun May 05 11:45:40 2002
+# $Header $
+#
+
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome
+
+
+@COMMENCE@
+
+# header files 
+EXPORT_HEADERS=
+
+# Libraries targets
+LIB = 
+
+LIB_SRC =
+
+LIB_MOC =
+
+LIB_CLIENT_IDL =
+
+LIB_SERVER_IDL = 
+
+EXPORT_PYSCRIPTS = 
+
+# additionnal information to compil and link file
+
+lib: notifqt.so
+
+notifqt.so: moc_notify.cpp
+       python setup.py install --install-lib=$(top_builddir)/lib/salome
+
+
+install: notifqt.so
+       $(INSTALL) -d $(libdir)
+       cp -p $(top_builddir)/lib/salome/notifqt.so $(libdir)
+
+
+#pattern rules
+moc_%.cpp : %.h
+       $(MOC) $< -o $@
diff --git a/src/TclQtNotifier/moc_notify.refcpp b/src/TclQtNotifier/moc_notify.refcpp
new file mode 100644 (file)
index 0000000..4f13f46
--- /dev/null
@@ -0,0 +1,183 @@
+/****************************************************************************
+** Notifier meta object code from reading C++ file 'notify.h'
+**
+** Created: Wed Feb 5 17:19:07 2003
+**      by: The Qt MOC ($Id: moc_notify.refcpp,v 1.1.2.1 2004/05/18 11:40:21 salome Exp $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "notify.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 19)
+#error "This file was generated using the moc from 3.0.6. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *Notifier::className() const
+{
+    return "Notifier";
+}
+
+QMetaObject *Notifier::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_Notifier;
+
+#ifndef QT_NO_TRANSLATION
+QString Notifier::tr( const char *s, const char *c )
+{
+    if ( qApp )
+       return qApp->translate( "Notifier", s, c, QApplication::DefaultCodec );
+    else
+       return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString Notifier::trUtf8( const char *s, const char *c )
+{
+    if ( qApp )
+       return qApp->translate( "Notifier", s, c, QApplication::UnicodeUTF8 );
+    else
+       return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* Notifier::staticMetaObject()
+{
+    if ( metaObj )
+       return metaObj;
+    QMetaObject* parentObject = QObject::staticMetaObject();
+    static const QUMethod slot_0 = {"dataReceived", 0, 0 };
+    static const QUMethod slot_1 = {"dataWritable", 0, 0 };
+    static const QUMethod slot_2 = {"dataExcept", 0, 0 };
+    static const QMetaData slot_tbl[] = {
+       { "dataReceived()", &slot_0, QMetaData::Public },
+       { "dataWritable()", &slot_1, QMetaData::Public },
+       { "dataExcept()", &slot_2, QMetaData::Public }
+    };
+    metaObj = QMetaObject::new_metaobject(
+       "Notifier", parentObject,
+       slot_tbl, 3,
+       0, 0,
+#ifndef QT_NO_PROPERTIES
+       0, 0,
+       0, 0,
+#endif // QT_NO_PROPERTIES
+       0, 0 );
+    cleanUp_Notifier.setMetaObject( metaObj );
+    return metaObj;
+}
+
+void* Notifier::qt_cast( const char* clname )
+{
+    if ( !qstrcmp( clname, "Notifier" ) ) return (Notifier*)this;
+    return QObject::qt_cast( clname );
+}
+
+bool Notifier::qt_invoke( int _id, QUObject* _o )
+{
+    switch ( _id - staticMetaObject()->slotOffset() ) {
+    case 0: dataReceived(); break;
+    case 1: dataWritable(); break;
+    case 2: dataExcept(); break;
+    default:
+       return QObject::qt_invoke( _id, _o );
+    }
+    return TRUE;
+}
+
+bool Notifier::qt_emit( int _id, QUObject* _o )
+{
+    return QObject::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool Notifier::qt_property( int _id, int _f, QVariant* _v)
+{
+    return QObject::qt_property( _id, _f, _v);
+}
+#endif // QT_NO_PROPERTIES
+
+
+const char *Timer::className() const
+{
+    return "Timer";
+}
+
+QMetaObject *Timer::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_Timer;
+
+#ifndef QT_NO_TRANSLATION
+QString Timer::tr( const char *s, const char *c )
+{
+    if ( qApp )
+       return qApp->translate( "Timer", s, c, QApplication::DefaultCodec );
+    else
+       return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString Timer::trUtf8( const char *s, const char *c )
+{
+    if ( qApp )
+       return qApp->translate( "Timer", s, c, QApplication::UnicodeUTF8 );
+    else
+       return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* Timer::staticMetaObject()
+{
+    if ( metaObj )
+       return metaObj;
+    QMetaObject* parentObject = QObject::staticMetaObject();
+    static const QUMethod slot_0 = {"timeout", 0, 0 };
+    static const QMetaData slot_tbl[] = {
+       { "timeout()", &slot_0, QMetaData::Public }
+    };
+    metaObj = QMetaObject::new_metaobject(
+       "Timer", parentObject,
+       slot_tbl, 1,
+       0, 0,
+#ifndef QT_NO_PROPERTIES
+       0, 0,
+       0, 0,
+#endif // QT_NO_PROPERTIES
+       0, 0 );
+    cleanUp_Timer.setMetaObject( metaObj );
+    return metaObj;
+}
+
+void* Timer::qt_cast( const char* clname )
+{
+    if ( !qstrcmp( clname, "Timer" ) ) return (Timer*)this;
+    return QObject::qt_cast( clname );
+}
+
+bool Timer::qt_invoke( int _id, QUObject* _o )
+{
+    switch ( _id - staticMetaObject()->slotOffset() ) {
+    case 0: timeout(); break;
+    default:
+       return QObject::qt_invoke( _id, _o );
+    }
+    return TRUE;
+}
+
+bool Timer::qt_emit( int _id, QUObject* _o )
+{
+    return QObject::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool Timer::qt_property( int _id, int _f, QVariant* _v)
+{
+    return QObject::qt_property( _id, _f, _v);
+}
+#endif // QT_NO_PROPERTIES
diff --git a/src/TclQtNotifier/notifqtmodule.cpp b/src/TclQtNotifier/notifqtmodule.cpp
new file mode 100644 (file)
index 0000000..721ef37
--- /dev/null
@@ -0,0 +1,873 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+using namespace std;
+#include <iostream>
+#include <sys/time.h>
+#include <Python.h>
+#include <sip.h>
+
+/*
+ * With Qt version 3.0, we must use this horrible hack : #define private public
+ * With Qt version > 3.0, this no more needed
+ * So commentarize #define QT30, with Qt version > 3.0
+ */
+#undef QT32
+#define QT30
+#ifdef QT30
+#define private public /* We need to use processNextEvent(),
+                             therefore we need
+                             access to the internal variables. */
+#include <qapplication.h>
+#undef private /* On revient au normal */
+#else
+#include <qapplication.h>
+#include <qeventloop.h>
+#endif
+
+#include <qsocketnotifier.h>
+
+
+#include "notify.h"
+#include <tk.h>
+
+extern "C" void QtFileProc(FileHandler *,int);
+extern "C" void QtTimerProc();
+extern "C" bool processQtEvent(bool );
+extern "C" int qtlooplevel();
+extern "C" void notifierFilter(int );
+
+//#define _DEBUG_
+# ifdef _DEBUG_
+# define HERE {cout<<flush ; cerr << "- Trace " << __FILE__ << " [" << __LINE__ << "] : " << flush ;}
+# define SCRUTE(var) {HERE ; cerr << #var << "=" << var << endl ;}
+# define MESSAGE(chain) {HERE ; cerr << chain << endl ;}
+#else
+# define HERE
+# define SCRUTE(var)
+# define MESSAGE(chain)
+#endif
+
+extern "C" int qtlooplevel(){
+#ifdef QT30
+   return qApp->loopLevel();
+#else
+   return qApp->eventLoop()->loopLevel();
+#endif
+}
+
+extern "C" bool processQtEvent(bool canWait)
+{
+    bool flag;
+    /*
+     * This function is called by WaitForEvent (internal loop of 
+     * Tcl Notifier) so only some Qt events will be taken in account.
+     * We install a filter on qApp
+     * before processing next qt event with wait.
+     */
+    notifierFilter(1);
+#ifdef QT30
+    flag= qApp->processNextEvent(canWait);
+#else
+    if(canWait){
+       flag= qApp->eventLoop()->processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMore );
+    }else{
+       flag= qApp->eventLoop()->processEvents(QEventLoop::AllEvents );
+    }
+#endif
+    notifierFilter(0);
+    return flag;
+}
+
+/*
+ *  This object (Notifier) calls QtFileProc when some data is present
+ *  on f->fd socket (Tk X11 socket)
+ */
+Notifier::Notifier(FileHandler *f,int mask):QObject()
+    {
+      fhdr=f;
+      if (mask & TCL_READABLE){
+        sn = new QSocketNotifier( f->fd, QSocketNotifier::Read );
+        QObject::connect( sn, SIGNAL(activated(int)), this, SLOT(dataReceived()) );
+      }else if (mask & TCL_WRITABLE){
+        sn = new QSocketNotifier( f->fd, QSocketNotifier::Write );
+        QObject::connect( sn, SIGNAL(activated(int)), this, SLOT(dataWritable()) );
+      }else if (mask & TCL_EXCEPTION){
+        sn = new QSocketNotifier( f->fd, QSocketNotifier::Exception );
+        QObject::connect( sn, SIGNAL(activated(int)), this, SLOT(dataExcept()) );
+      }
+    }
+
+void Notifier::dataReceived()
+    {
+        //fprintf(stderr,"dataReceived\n");
+        QtFileProc(fhdr,TCL_READABLE);
+    }
+void Notifier::dataWritable()
+    {
+        //fprintf(stderr,"dataWritable\n");
+        QtFileProc(fhdr,TCL_WRITABLE);
+    }
+void Notifier::dataExcept()
+    {
+        //fprintf(stderr,"dataExcept\n");
+        QtFileProc(fhdr,TCL_EXCEPTION);
+    }
+
+Timer::Timer():QObject()
+{
+      // Create a QT timer
+      timer= new QTimer(this);
+      // Connect it    
+      connect( timer, SIGNAL(timeout()), this,SLOT(timeout()) );
+      // but don't start it
+}
+void Timer::timeout()
+{
+   MESSAGE("timeout");
+   /*
+    * QT timer associated to Tcl notifier has fired
+    * stop it
+    * and call Tcl notifier function QtTimerProc
+    */
+   timer->stop();
+   QtTimerProc();
+}
+
+
+Filter::Filter():QObject()
+{
+   mustFilter=0;
+   // Install it as an application-global event filter to catch ...
+   SCRUTE(qApp);
+   qApp->installEventFilter( this );
+}
+
+bool Filter::eventFilter( QObject *obj, QEvent *event )
+{
+   MESSAGE("Filter::eventFilter");
+   SCRUTE(event->type());
+   if (mustFilter){
+      /*
+       * We are in a modal TK loop (WaitForEvent has been called)
+       * so we ignore some Qt events
+       */
+      if(event->type() == QEvent::MouseButtonPress) return TRUE; 
+      if(event->type() == QEvent::MouseButtonRelease)return TRUE;
+      if(event->type() == QEvent::MouseButtonDblClick)return TRUE;
+      //if(event->type() == QEvent::KeyPress)return TRUE;
+      if(event->type() == 6)return TRUE; 
+      //if(event->type() == QEvent::KeyRelease)return TRUE;
+      if(event->type() == 7)return TRUE; 
+      // We don't allow to close Qt windows in Tk modal loop
+      if(event->type() == QEvent::Close)return TRUE;
+   }
+   return QObject::eventFilter( obj, event ); // don't eat event
+}
+
+/*
+ * The following structure is what is added to the Tcl event queue when
+ * file handlers are ready to fire.
+ */
+
+typedef struct FileHandlerEvent {
+    Tcl_Event header;           /* Information that is standard for
+                                 * all events. */
+    int fd;                     /* File descriptor that is ready.  Used
+                                 * to find the FileHandler structure for
+                                 * the file (can't point directly to the
+                                 * FileHandler structure because it could
+                                 * go away while the event is queued). */
+} FileHandlerEvent;
+
+/*
+ * The following static structure contains the state information for the
+ * Qt based implementation of the Tcl notifier.
+ */
+
+static struct NotifierState {
+    int currentTimeout;
+    Filter *filter;
+    Timer *timer;
+    FileHandler *firstFileHandlerPtr;   /* Pointer to head of file handler
+                                         * list. */
+} notifier;
+
+/*
+ * The following static indicates whether this module has been initialized.
+ */
+static int initialized = 0;
+
+extern "C" void  InitNotifier (void);
+
+static Tk_RestrictAction EventRestrictProc(ClientData arg, XEvent *eventPtr)
+{
+   /*
+    * We are in a modal QT loop (qApp->loopLevel() > 1)
+    * so we ignore some TK events
+    */
+   //printf("event : %d\n",eventPtr->type);
+   if (qtlooplevel() == 1) return TK_PROCESS_EVENT;
+   if(eventPtr->type == ButtonRelease)return TK_DISCARD_EVENT;
+   if(eventPtr->type == ButtonPress)return TK_DISCARD_EVENT;
+   if(eventPtr->type == KeyRelease)return TK_DISCARD_EVENT;
+   if(eventPtr->type == KeyPress)return TK_DISCARD_EVENT;
+   if(eventPtr->type == MotionNotify)return TK_DISCARD_EVENT;
+   return TK_PROCESS_EVENT;
+}
+
+static void restrictevents()
+{
+    ClientData info,oldArg;
+    //if (qtlooplevel()>1) Tk_RestrictEvents(EventRestrictProc,&info,&oldArg);
+    if (qtlooplevel()>0) Tk_RestrictEvents(EventRestrictProc,&info,&oldArg);
+    else Tk_RestrictEvents(NULL,&info,&oldArg);
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetTimer --
+ *
+ *      This procedure sets the current notifier timeout value.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Replaces any previous timer.
+ *
+ * This function starts or stops the notifier timer
+ * It called when Tcl_SetTime(xxx) is called
+ * This notifier timer calls QtTimerProc when timer event occurs
+ *----------------------------------------------------------------------
+ */
+
+static void
+SetTimer(Tcl_Time *timePtr)
+         /* Timeout value, may be NULL. */
+{
+    long timeout;
+    MESSAGE("SetTimer");
+
+    if (!initialized) {
+        InitNotifier();
+    }
+
+    if (notifier.currentTimeout != 0) {
+        // stopQtTimer();
+        // printf("stop timer \n");
+        notifier.timer->timer->stop();
+        notifier.currentTimeout = 0;
+    }
+    if (timePtr) {
+        timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
+        // startQtTimer(timeout);
+        // printf("start timer %ld\n",timeout);
+        notifier.timer->timer->start(timeout);
+        notifier.currentTimeout = 1;
+    }
+}
+
+/*
+ *  Ask _tkinter to service all pending events
+ */
+
+static void DoEvents()
+{
+  long ret=1;
+  MESSAGE("DoEvents");
+  SIP_BLOCK_THREADS
+  //Tcl_ServiceAll();
+  PyObject * tkinter=PyImport_ImportModule("_tkinter");
+  while(ret==1){
+    // Process one Tcl event without blocking
+    MESSAGE("dooneevent call");
+    PyObject *res=PyObject_CallMethod(tkinter,"dooneevent","i",2);
+    if(!res){
+      PyErr_Print();
+      SIP_UNBLOCK_THREADS
+      return;
+    }
+    ret= PyInt_AsLong(res);
+    SCRUTE(ret);
+    Py_DECREF(res);
+    //SCRUTE(res->ob_refcnt);
+    // usleep(20000);
+  }
+
+  Py_DECREF(tkinter);
+  SCRUTE(tkinter->ob_refcnt);
+  SIP_UNBLOCK_THREADS
+  MESSAGE("end of DoEvents");
+  return;
+}
+
+/*
+ * If running is 1, we have already called DoEvents and so dooneevent from
+ * _tkinter module. It's a recursive call so don't call again DoEvents
+ * it will block.We are in Tcl so it's safe to call directly Tcl_ServiceAll.
+ * If running is 0, we are running out of _tkinter module so we must
+ * call Tcl_ServiceAll through dooneevent from _tkinter module
+ */
+static int running=1;
+static int waitfor=0;
+/*
+ * ServiceAll could be called recursively so be careful
+ */
+static void ServiceAll()
+{
+  if(running==1){
+    // It's safe to call directly Tcl_ServiceAll
+    Tcl_ServiceAll();
+  }else if(waitfor==1){
+    // It's safe to call directly Tcl_ServiceAll
+    Tcl_ServiceAll();
+  }else{
+    // Call Tcl_ServiceAll through Python _tkinter module interface
+    // to have safe state
+    running=1;
+    DoEvents();
+    running=0;
+  }
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * QtTimerProc --
+ *
+ *      This procedure is the QtTimerCallbackProc used to handle
+ *      timeouts.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Processes all queued events.
+ *
+ * This function is declared to the Tcl notifier 
+ *     notifierprocs.setTimerProc = SetTimer;
+ *  Tcl_SetNotifier(&notifierprocs);
+ *  This function is called when a timer event occurs
+ *----------------------------------------------------------------------
+ */
+
+void QtTimerProc()
+{
+    MESSAGE("QtTimerProc");
+    restrictevents();
+    ServiceAll();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CreateFileHandler --
+ *
+ *      This procedure registers a file handler with the Qt notifier.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Creates a new file handler structure and registers one or more
+ *      input procedures with Qt.
+ *
+ *----------------------------------------------------------------------
+ * CCAR:
+ *    Cette procedure est appelee par Tcl via le notifier (notifier.createFileHandlerProc)
+ *    Elle est chargée d'enregistrer dans la boucle Qt un file handler dont le file
+ * descripteur sera celui de la connexion X spécifique de Tk.
+ *   Ainsi on peut deriver le traitement des evenements X de Tk vers les procedures
+ *   qui sont localisées dans ce fichier
+ * This function is declared to the Tcl notifier 
+ *  notifierprocs.createFileHandlerProc = CreateFileHandler
+ *  Tcl_SetNotifier(&notifierprocs);
+ * Then Tcl calls it during initialization : ????
+ */
+
+static void
+CreateFileHandler(int fd, int mask, Tcl_FileProc proc, ClientData clientData)
+/*    int fd;                        Handle of stream to watch. 
+ *    int mask;                      OR'ed combination of TCL_READABLE,
+ *                                 TCL_WRITABLE, and TCL_EXCEPTION:
+ *                                 indicates conditions under which
+ *                                 proc should be called. 
+ *  Tcl_FileProc *proc;            Procedure to call for each
+ *                                 selected event. 
+ *  ClientData clientData;         Arbitrary data to pass to proc. 
+ */
+{
+    FileHandler *filePtr;
+
+    MESSAGE("CreateFileHandler");
+
+    if (!initialized) {
+        InitNotifier();
+    }
+
+    for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL;
+            filePtr = filePtr->nextPtr) {
+        if (filePtr->fd == fd) {
+            break;
+        }
+    }
+    if (filePtr == NULL) {
+        filePtr = (FileHandler*) ckalloc(sizeof(FileHandler));
+        filePtr->fd = fd;
+        filePtr->readyMask = 0;
+        filePtr->mask = 0;
+        filePtr->nextPtr = notifier.firstFileHandlerPtr;
+        notifier.firstFileHandlerPtr = filePtr;
+    }
+    filePtr->proc = proc;
+    filePtr->clientData = clientData;
+    /*
+     * Enregistrement avec la boucle Qt
+     *  Toute activité sur le file descripteur fd (connexion X spécifique Tk)
+     *  sera détectée et redirigée vers la procédure QtFileProc
+     * Create a Notifier object to redirect X11 events present on socket filePtr->fd
+     * towards QtFileProc
+     */
+    filePtr->qtNotifier=new Notifier(filePtr,mask);
+
+    filePtr->mask = mask;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteFileHandler --
+ *
+ *      Cancel a previously-arranged callback arrangement for
+ *      a file.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      If a callback was previously registered on file, remove it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteFileHandler(int fd)
+/*
+ *  int fd;                      Stream id for which to remove
+ *                               callback procedure. 
+ */
+{
+    FileHandler *filePtr, *prevPtr;
+
+    if (!initialized) {
+        InitNotifier();
+    }
+
+    /*
+     * Find the entry for the given file (and return if there
+     * isn't one).
+     */
+
+    for (prevPtr = NULL, filePtr = notifier.firstFileHandlerPtr; ;
+            prevPtr = filePtr, filePtr = filePtr->nextPtr) {
+        if (filePtr == NULL) {
+            return;
+        }
+        if (filePtr->fd == fd) {
+            break;
+        }
+    }
+
+    /*
+     * Clean up information in the callback record.
+     */
+
+    if (prevPtr == NULL) {
+        notifier.firstFileHandlerPtr = filePtr->nextPtr;
+    } else {
+        prevPtr->nextPtr = filePtr->nextPtr;
+    }
+    /*
+     * Destruction du notifier Qt
+     */
+    delete filePtr->qtNotifier;
+
+    ckfree((char *) filePtr);
+}
+
+static int FileHandlerEventProc(Tcl_Event *evPtr, int flags);
+/*
+ *----------------------------------------------------------------------
+ *
+ * QtFileProc --
+ *
+ *      These procedures are called by Qt when a file becomes readable,
+ *      writable, or has an exception.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Makes an entry on the Tcl event queue if the event is
+ *      interesting.
+ *
+ *----------------------------------------------------------------------
+ *  Lorsqu'une activité est detectée sur le file descripteur fd cette
+ *  procédure crée un evenement Tcl qu'elle rajoute dans la queue Tcl
+ *  Elle demande ensuite de servir (Tcl_ServiceAll) tous les evenements
+ *  Tcl présents dans la queue Tcl
+ *  L'evenement est créé avec comme procédure de traitement associée FileHandlerEventProc
+ */
+
+void QtFileProc(FileHandler *filePtr,int mask)
+{
+    FileHandlerEvent *fileEvPtr;
+    MESSAGE("QtFileProc");
+
+    /*
+     * Ignore unwanted or duplicate events.
+     */
+
+    if (!(filePtr->mask & mask) || (filePtr->readyMask & mask)) {
+        return;
+    }
+
+    /*
+     * This is an interesting event, so put it onto the event queue.
+     *  On demande qu'il soit traité avec la procédure FileHandlerEventProc
+     */
+
+    filePtr->readyMask |= mask;
+
+    fileEvPtr = (FileHandlerEvent *) ckalloc(sizeof(FileHandlerEvent));
+    fileEvPtr->header.proc = FileHandlerEventProc;
+    fileEvPtr->fd = filePtr->fd;
+    Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);
+
+    /*
+     * Process events on the Tcl event queue before returning to Qt.
+     */
+
+    // On entre dans la boucle de traitement des evenements Tcl (retour vers Python?)
+    /*
+     * L'evenement file sera traité ce qui conduit à mettre les evenements X
+     * dans la queue Tcl. Ces evenements (X) seront alors traités dans la foulée
+     * La source d'evenement X enregistrée par Tcl_CreateEventSource est egalement
+     * consultée pendant cette phase (assertion a verifier)
+     */
+
+    restrictevents();
+    ServiceAll();
+
+    // On revient vers la boucle Qt
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileHandlerEventProc --
+ *
+ *      This procedure is called by Tcl_ServiceEvent when a file event
+ *      reaches the front of the event queue.  This procedure is
+ *      responsible for actually handling the event by invoking the
+ *      callback for the file handler.
+ *
+ * Results:
+ *      Returns 1 if the event was handled, meaning it should be removed
+ *      from the queue.  Returns 0 if the event was not handled, meaning
+ *      it should stay on the queue.  The only time the event isn't
+ *      handled is if the TCL_FILE_EVENTS flag bit isn't set.
+ *
+ * Side effects:
+ *      Whatever the file handler's callback procedure does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileHandlerEventProc(Tcl_Event *evPtr, int flags)
+/*
+ *  Tcl_Event *evPtr;            Event to service. 
+ *  int flags;                   Flags that indicate what events to
+ *                               handle, such as TCL_FILE_EVENTS. 
+ */
+{
+    FileHandler *filePtr;
+    FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr;
+    int mask;
+    MESSAGE("FileHandlerEventProc");
+
+    if (!(flags & TCL_FILE_EVENTS)) {
+        return 0;
+    }
+
+    /*
+     * Search through the file handlers to find the one whose handle matches
+     * the event.  We do this rather than keeping a pointer to the file
+     * handler directly in the event, so that the handler can be deleted
+     * while the event is queued without leaving a dangling pointer.
+     */
+
+    for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL;
+            filePtr = filePtr->nextPtr) {
+        if (filePtr->fd != fileEvPtr->fd) {
+            continue;
+        }
+
+        /*
+         * The code is tricky for two reasons:
+         * 1. The file handler's desired events could have changed
+         *    since the time when the event was queued, so AND the
+         *    ready mask with the desired mask.
+         * 2. The file could have been closed and re-opened since
+         *    the time when the event was queued.  This is why the
+         *    ready mask is stored in the file handler rather than
+         *    the queued event:  it will be zeroed when a new
+         *    file handler is created for the newly opened file.
+         */
+
+        mask = filePtr->readyMask & filePtr->mask;
+        filePtr->readyMask = 0;
+        if (mask != 0) {
+            // On utilise ici la procédure enregistrée avec le file handler
+            // Normalement il s'agit de DisplayFileProc (fichier unix/tkUnixEvent.c de Tk)
+            (*filePtr->proc)(filePtr->clientData, mask);
+        }
+        break;
+    }
+    return 1;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WaitForEvent --
+ *
+ *      This function is called by Tcl_DoOneEvent to wait for new
+ *      events on the message queue.  If the block time is 0, then
+ *      Tcl_WaitForEvent just polls without blocking.
+ *
+ * Results:
+ *      Returns 1 if an event was found, else 0.  This ensures that
+ *      Tcl_DoOneEvent will return 1, even if the event is handled
+ *      by non-Tcl code.
+ *
+ * Side effects:
+ *      Queues file events that are detected by the select.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WaitForEvent(
+    Tcl_Time *timePtr)          /* Maximum block time, or NULL. */
+{
+    int ret;
+    //bool old_app_exit_loop;
+    int timeout;
+    MESSAGE("WaitForEvent");
+
+    if (!initialized) {
+        InitNotifier();
+    }
+
+    //SCRUTE(Tk_GetNumMainWindows());
+    //if(Tk_GetNumMainWindows()<1){
+       // That should not have happened. quit now ???
+       //qApp->quit();
+    //}
+
+    if (timePtr) {
+        // Wait with timeout
+        MESSAGE("Have timeout");
+        timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
+        if (timeout == 0) {
+            // Try to process one event without waiting
+            MESSAGE("Process an event without waiting");
+            /*
+             * We are already in Tkinter module so Tcl calls
+             * should be done directly without using DoEvents
+             * wrapping
+             */
+           SCRUTE(running);
+            waitfor=1;
+            ret=processQtEvent(FALSE);
+           waitfor=0;
+            if (ret) {
+                MESSAGE("Qt event caught");
+                // an event has been proccessed
+                return 1;
+            } else {
+                // no event has been proccessed
+                MESSAGE("No Qt event caught");
+                return 0;
+            }
+        } else {
+            MESSAGE("Start the timer");
+            Tcl_SetTimer(timePtr);
+        }
+    } else {
+      // timePtr == NULL, blocking wait of an event
+    }
+    // Blocking wait
+    MESSAGE("Wait an event");
+    SCRUTE(running);
+    waitfor=1;
+    ret=processQtEvent(TRUE);
+    waitfor=0;
+/*
+    if(ret==FALSE && qApp->app_exit_loop == TRUE){
+      MESSAGE("Critical : qt loop is ended and we will loop forever");
+      old_app_exit_loop = qApp->app_exit_loop;
+      qApp->app_exit_loop=FALSE;
+      processQtEvent(TRUE);
+      qApp->app_exit_loop=old_app_exit_loop;
+    }
+*/
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NotifierExitHandler --
+ *
+ *      This function is called to cleanup the notifier state before
+ *      Tcl is unloaded.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Destroys the notifier window.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+NotifierExitHandler(
+    ClientData clientData)      /* Not used. */
+{
+    delete notifier.timer;
+    delete notifier.filter;
+
+    for (; notifier.firstFileHandlerPtr != NULL; ) {
+        Tcl_DeleteFileHandler(notifier.firstFileHandlerPtr->fd);
+    }
+    initialized = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InitNotifier --
+ *
+ *      Initializes the notifier state.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Creates a new exit handler.
+ *
+ *----------------------------------------------------------------------
+ * La procedure InitNotifier doit etre appelée avant d'initialiser Tcl et Tk
+ * par Tcl_Init et Tk_Init
+ * Tcl_SetNotifier enregistre les procedures du notifier aupres de Tcl
+ * et en particulier notifier.createFileHandlerProc en tant que tclStubs.tcl_CreateFileHandler
+ * lui meme appelé par Tcl_CreateFileHandler qui est appelé à l'initialisation par
+ * TkpOpenDisplay avec comme argument proc : DisplayFileProc
+ * TkpOpenDisplay est lui meme appelé par GetScreen qui est appelé à l'initialisation
+ * par CreateTopLevelWindow
+ *
+ * Tk_Init appelle Initialize qui
+ *  1 - crée une toplevel par appel à TkCreateFrame
+ *      cette création a comme effet de bord l'appel à GetScreen
+ *  2 - appelle TkpInit qui réalise des initialisations spécifiques
+ *      dont TkCreateXEventSource() qui crée une source d'évenements Tcl par
+ *      Tcl_CreateEventSource(DisplaySetupProc, DisplayCheckProc, NULL);
+ *      Cette source est enregistrée dans la liste des sources qui mémorise
+ *      les procédures dans source->setupProc et source->checkProc
+ *      Les sources sont appelées par Tcl_ServiceAll qui appelle Tcl_ServiceEvent
+ *      qui traite un evenement
+ *
+ * La procédure DisplayFileProc appelle TransferXEventsToTcl qui met les evenements
+ * X dans la queue Tk en appelant Tk_QueueWindowEvent
+ * Tk_QueueWindowEvent appelle soit Tcl_DoWhenIdle soit Tcl_QueueEvent pour mettre
+ * cet evenement dans la queue Tcl
+ * Tcl_QueueEvent appelle QueueEvent qui fait le travail
+ *
+ */
+
+extern "C" void InitNotifier()
+{
+    MESSAGE("InitNotifier");
+
+    /*
+     * Only reinitialize if we are not in exit handling. The notifier
+     * can get reinitialized after its own exit handler has run, because
+     * of exit handlers for the I/O and timer sub-systems (order dependency).
+     */
+
+    if (TclInExit()) {
+        return;
+    }
+    initialized = 1;
+    memset(&notifier, 0, sizeof(notifier));
+    notifier.timer= new Timer();
+    notifier.filter= new Filter();
+
+    Tcl_SetServiceMode(TCL_SERVICE_ALL);
+}
+
+ClientData
+initNotifierProc()
+{
+return (ClientData) 0;
+}
+
+void InitNotifierProcs()
+{
+    Tcl_NotifierProcs notifierprocs;
+    MESSAGE("InitNotifierProcs");
+    memset(&notifierprocs, 0, sizeof(notifierprocs));
+    notifierprocs.createFileHandlerProc = CreateFileHandler;
+    notifierprocs.deleteFileHandlerProc = DeleteFileHandler;
+    notifierprocs.setTimerProc = SetTimer;
+    notifierprocs.waitForEventProc = WaitForEvent;
+#if TCL_MINOR_VERSION > 3
+    notifierprocs.initNotifierProc = initNotifierProc;
+#endif
+    MESSAGE("Tcl_SetNotifier");
+    Tcl_SetNotifier(&notifierprocs);
+    MESSAGE("Tcl_CreateExitHandler");
+    Tcl_CreateExitHandler(NotifierExitHandler, NULL);
+}
+
+extern "C" void notifierFilter(int filter)
+{
+    notifier.filter->mustFilter=filter;
+}
+
+static PyMethodDef Module_Methods[] =
+  {
+    {NULL, NULL}
+  };
+
+extern "C" void initnotifqt()
+{
+PyObject *m;
+static char modulename[] = "notifqt";
+MESSAGE("initnotifqt");
+// Protect Tcl notifier if qApp is not started
+if(qApp) InitNotifierProcs();
+/*
+ * If the module is linked with the right lib (qt-mt)
+ * this module and libqtcmodule share global variables as qApp
+ * and others
+ */
+// We are called from Python so initialize the ServiceAll trick.
+running=0;
+m = Py_InitModule(modulename, Module_Methods);
+}
diff --git a/src/TclQtNotifier/notify.h b/src/TclQtNotifier/notify.h
new file mode 100644 (file)
index 0000000..00f908b
--- /dev/null
@@ -0,0 +1,55 @@
+#include <qobject.h>
+#include <qwidget.h>
+#include <qsocketnotifier.h> 
+#include <qtimer.h>
+
+#include <tcl.h>
+EXTERN int              TclInExit _ANSI_ARGS_((void));
+
+class Notifier;
+
+typedef struct FileHandler {
+    int fd;
+    int mask;                   /* Mask of desired events: TCL_READABLE, etc. */
+    int readyMask;              /* Events that have been seen since the
+                                   last time FileHandlerEventProc was called
+                                   for this file. */
+    Notifier *qtNotifier;
+    Tcl_FileProc *proc;         /* Procedure to call, in the style of
+                                 * Tcl_CreateFileHandler. */
+    ClientData clientData;      /* Argument to pass to proc. */
+    struct FileHandler *nextPtr;/* Next in list of all files we care about. */
+} FileHandler;
+
+class Notifier : public QObject
+{
+    Q_OBJECT
+public:
+    Notifier(FileHandler *,int);
+public slots:
+    void dataReceived();
+    void dataWritable();
+    void dataExcept();
+private: 
+    QSocketNotifier *sn;
+    FileHandler *fhdr;
+};
+
+class Filter : public QObject
+{
+public:
+    Filter();
+    bool eventFilter( QObject *, QEvent * );
+    int mustFilter;
+};
+
+class Timer : public QObject
+{
+    Q_OBJECT
+public:
+    Timer();
+    QTimer *timer;
+public slots:
+    void timeout();
+};
+
diff --git a/src/TclQtNotifier/setup.py.in b/src/TclQtNotifier/setup.py.in
new file mode 100644 (file)
index 0000000..0ac1b11
--- /dev/null
@@ -0,0 +1,75 @@
+from distutils.core import setup, Extension
+
+import os,sys
+
+TCLHOME=os.getenv("TCLHOME")
+if not TCLHOME:
+   print "TCLHOME not set : use /usr"
+   TCLHOME="/usr"
+TKINCL=os.path.join(TCLHOME,"include")
+
+QT_INCLUDES="@QT_INCLUDES@".split()
+SIP_INCLUDES="@SIP_INCLUDES@".split()
+QT_LIBS="@QT_MT_LIBS@".split()
+PYQT_LIBS="@PYQT_LIBS@".split()
+
+PYDIR=sys.prefix
+VERS="%s.%s" % (sys.version_info[0],sys.version_info[1])
+
+def find_file(filename, std_dirs, paths):
+    """Searches for the directory where a given file is located,
+    and returns a possibly-empty list of additional directories, or None
+    if the file couldn't be found at all.
+
+    'filename' is the name of a file, such as readline.h or libcrypto.a.
+    'std_dirs' is the list of standard system directories; if the
+        file is found in one of them, no additional directives are needed.
+    'paths' is a list of additional locations to check; if the file is
+        found in one of them, the resulting list will contain the directory.
+    """
+
+    # Check the standard locations
+    for dir in std_dirs:
+        f = os.path.join(dir, filename)
+        if os.path.exists(f): return []
+
+    # Check the additional directories
+    for dir in paths:
+        f = os.path.join(dir, filename)
+        if os.path.exists(f):
+            return [dir]
+
+    # Not found anywhere
+    return None
+
+inc_dirs=[TKINCL]
+
+for version in ['8.4', '8.3', '8.2', '8.1', '8.0']:
+    # Check for the include files on Debian, where
+    # they're put in /usr/include/{tcl,tk}X.Y
+    debian_tcl_include = [ '/usr/include/tcl' + version ]
+    debian_tk_include =  [ '/usr/include/tk'  + version ] + debian_tcl_include
+    tcl_includes = find_file('tcl.h', inc_dirs, debian_tcl_include)
+    tk_includes = find_file('tk.h', inc_dirs, debian_tk_include)
+    if tcl_includes and tk_includes:
+       break
+
+print "Found Tk version:",version
+print "Found Tcl includes:",tcl_includes
+print "Found Tk includes:",tk_includes
+
+include_dirs=[".", "@srcdir@", TKINCL]+tcl_includes+tk_includes
+libs_tk=["tk"+version,"tcl"+version]
+
+setup(name="notifqt", version="1.0",
+    ext_modules=[
+             Extension("notifqt", ["@srcdir@/notifqtmodule.cpp", "moc_notify.cpp", ],
+                        include_dirs=include_dirs,
+                        library_dirs=[ ],
+                        libraries=libs_tk,
+                        extra_compile_args= SIP_INCLUDES + QT_INCLUDES,
+                        extra_objects=[],
+                        extra_link_args=QT_LIBS + PYQT_LIBS ,
+                      )
+                ])
+
diff --git a/src/patchTkinter/Makefile.in b/src/patchTkinter/Makefile.in
new file mode 100644 (file)
index 0000000..dcea295
--- /dev/null
@@ -0,0 +1,43 @@
+# -* Makefile *- 
+#
+# Author : Nicolas REJNERI
+# Date   : Sun May 05 11:45:40 2002
+# $Header $
+#
+
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome
+
+
+@COMMENCE@
+
+# header files 
+EXPORT_HEADERS=
+
+# Libraries targets
+LIB = 
+
+LIB_SRC =
+
+LIB_MOC =
+
+LIB_CLIENT_IDL =
+
+LIB_SERVER_IDL = 
+
+EXPORT_PYSCRIPTS = 
+
+# additionnal information to compil and link file
+
+_tkinter.so: 
+       python setup.py install --install-lib=$(top_builddir)/lib/salome
+
+lib: _tkinter.so
+
+install: _tkinter.so
+       $(INSTALL) -d $(libdir)
+       cp -p $(top_builddir)/lib/salome/_tkinter.so $(libdir)
+
diff --git a/src/patchTkinter/_tkinter.c b/src/patchTkinter/_tkinter.c
new file mode 100644 (file)
index 0000000..35e9bbb
--- /dev/null
@@ -0,0 +1,2318 @@
+/***********************************************************
+Copyright (C) 1994 Steen Lumholt.
+
+                        All Rights Reserved
+
+******************************************************************/
+
+/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
+
+/* TCL/TK VERSION INFO:
+
+       Only Tcl/Tk 8.0 and later are supported.  Older versions are not
+       supported.  (Use Python 1.5.2 if you cannot upgrade your Tcl/Tk
+       libraries.)
+*/
+
+/* XXX Further speed-up ideas, involving Tcl 8.0 features:
+
+   - In Tcl_Call(), create Tcl objects from the arguments, possibly using
+   intelligent mappings between Python objects and Tcl objects (e.g. ints,
+   floats and Tcl window pointers could be handled specially).
+
+   - Register a new Tcl type, "Python callable", which can be called more
+   efficiently and passed to Tcl_EvalObj() directly (if this is possible).
+
+*/
+
+
+#include "Python.h"
+#include <ctype.h>
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+#endif
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+#endif
+
+#ifdef macintosh
+#define MAC_TCL
+#endif
+
+#ifdef TK_FRAMEWORK
+#include <Tcl/tcl.h>
+#include <Tk/tk.h>
+#else
+#include <tcl.h>
+#include <tk.h>
+#endif
+
+#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
+
+#if TKMAJORMINOR < 8000
+#error "Tk older than 8.0 not supported"
+#endif
+
+#if defined(macintosh)
+/* Sigh, we have to include this to get at the tcl qd pointer */
+#include <tkMac.h>
+/* And this one we need to clear the menu bar */
+#include <Menus.h>
+#endif
+
+#if !(defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(macintosh))
+/* Mac has it, but it doesn't really work:-( */
+#define HAVE_CREATEFILEHANDLER
+#endif
+
+#ifdef HAVE_CREATEFILEHANDLER
+
+/* Tcl_CreateFileHandler() changed several times; these macros deal with the
+   messiness.  In Tcl 8.0 and later, it is not available on Windows (and on
+   Unix, only because Jack added it back); when available on Windows, it only
+   applies to sockets. */
+
+#ifdef MS_WINDOWS
+#define FHANDLETYPE TCL_WIN_SOCKET
+#else
+#define FHANDLETYPE TCL_UNIX_FD
+#endif
+
+/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
+   which uses this to handle Tcl events while the user is typing commands. */
+
+#if FHANDLETYPE == TCL_UNIX_FD
+#define WAIT_FOR_STDIN
+#endif
+
+#endif /* HAVE_CREATEFILEHANDLER */
+
+#ifdef MS_WINDOWS
+#include <conio.h>
+#define WAIT_FOR_STDIN
+#endif
+
+#ifdef WITH_THREAD
+
+/* The threading situation is complicated.  Tcl is not thread-safe, except for
+   Tcl 8.1, which will probably remain in alpha status for another 6 months
+   (and the README says that Tk will probably remain thread-unsafe forever).
+   So we need to use a lock around all uses of Tcl.  Previously, the Python
+   interpreter lock was used for this.  However, this causes problems when
+   other Python threads need to run while Tcl is blocked waiting for events.
+
+   To solve this problem, a separate lock for Tcl is introduced.  Holding it
+   is incompatible with holding Python's interpreter lock.  The following four
+   macros manipulate both locks together.
+
+   ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
+   Py_END_ALLOW_THREADS.  They should be used whenever a call into Tcl is made
+   that could call an event handler, or otherwise affect the state of a Tcl
+   interpreter.  These assume that the surrounding code has the Python
+   interpreter lock; inside the brackets, the Python interpreter lock has been 
+   released and the lock for Tcl has been acquired.
+
+   Sometimes, it is necessary to have both the Python lock and the Tcl lock.
+   (For example, when transferring data from the Tcl interpreter result to a
+   Python string object.)  This can be done by using different macros to close
+   the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
+   the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
+   releases the Tcl lock.
+
+   By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
+   handlers when the handler needs to use Python.  Such event handlers are
+   entered while the lock for Tcl is held; the event handler presumably needs
+   to use Python.  ENTER_PYTHON releases the lock for Tcl and acquires
+   the Python interpreter lock, restoring the appropriate thread state, and
+   LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
+   for Tcl.  It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
+   the code between ENTER_PYTHON and LEAVE_PYTHON.
+
+   These locks expand to several statements and brackets; they should not be
+   used in branches of if statements and the like.
+
+*/
+
+static PyThread_type_lock tcl_lock = 0;
+static PyThreadState *tcl_tstate = NULL;
+
+#define ENTER_TCL \
+       { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
+           PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
+
+#define LEAVE_TCL \
+    tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
+
+#define ENTER_OVERLAP \
+       Py_END_ALLOW_THREADS
+
+#define LEAVE_OVERLAP_TCL \
+       tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
+
+#define ENTER_PYTHON \
+       { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
+            PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
+
+#define LEAVE_PYTHON \
+       { PyThreadState *tstate = PyEval_SaveThread(); \
+            PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
+
+#else
+
+#define ENTER_TCL
+#define LEAVE_TCL
+#define ENTER_OVERLAP
+#define LEAVE_OVERLAP_TCL
+#define ENTER_PYTHON
+#define LEAVE_PYTHON
+
+#endif
+
+/*
+ * EDF-CCAR : Ajout de la fonction PyServiceAll
+ */
+
+#ifdef WITH_THREAD
+#warning "avec thread"
+void PyServiceAll(void){
+  if(tcl_tstate != NULL){
+    /*
+     *  We are already in the Tcl protected zone
+     *  No need to acquire the tcl_lock (it's already on)
+     */
+    Tcl_ServiceAll();
+    return;
+  }
+  /*
+   *  We are not in the Tcl protected zone
+   *  Must acquire the tcl_lock
+   */
+    ENTER_TCL
+      Tcl_ServiceAll();
+    LEAVE_TCL
+}
+#else
+#warning "sans thread"
+void PyServiceAll(void){
+  Tcl_ServiceAll();
+}
+#endif
+
+/*
+ * EDF-CCAR : Fin de la fonction PyServiceAll
+ */
+
+#ifdef macintosh
+
+/*
+** Additional cruft needed by Tcl/Tk on the Mac.
+** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
+*/
+
+/* ckfree() expects a char* */
+#define FREECAST (char *)
+
+#include <Events.h> /* For EventRecord */
+
+typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
+void Tcl_MacSetEventProc(TclMacConvertEventPtr procPtr);
+int TkMacConvertEvent(EventRecord *eventPtr);
+
+staticforward int PyMacConvertEvent(EventRecord *eventPtr);
+
+#include <SIOUX.h>
+extern int SIOUXIsAppWindow(WindowPtr);
+
+#endif /* macintosh */
+
+#ifndef FREECAST
+#define FREECAST (char *)
+#endif
+
+/**** Tkapp Object Declaration ****/
+
+staticforward PyTypeObject Tkapp_Type;
+
+typedef struct {
+       PyObject_HEAD
+       Tcl_Interp *interp;
+} TkappObject;
+
+#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
+#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
+#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
+
+#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
+(void *) v, ((PyObject *) v)->ob_refcnt))
+
+
+\f
+/**** Error Handling ****/
+
+static PyObject *Tkinter_TclError;
+static int quitMainLoop = 0;
+static int errorInCmd = 0;
+static PyObject *excInCmd;
+static PyObject *valInCmd;
+static PyObject *trbInCmd;
+
+
+\f
+static PyObject *
+Tkinter_Error(PyObject *v)
+{
+       PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
+       return NULL;
+}
+
+
+\f
+/**** Utils ****/
+
+#ifdef WITH_THREAD
+#ifndef MS_WINDOWS
+
+/* Millisecond sleep() for Unix platforms. */
+
+static void
+Sleep(int milli)
+{
+       /* XXX Too bad if you don't have select(). */
+       struct timeval t;
+       t.tv_sec = milli/1000;
+       t.tv_usec = (milli%1000) * 1000;
+       select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
+}
+#endif /* MS_WINDOWS */
+#endif /* WITH_THREAD */
+
+\f
+static char *
+AsString(PyObject *value, PyObject *tmp)
+{
+       if (PyString_Check(value))
+               return PyString_AsString(value);
+#ifdef Py_USING_UNICODE
+       else if (PyUnicode_Check(value)) {
+               PyObject *v = PyUnicode_AsUTF8String(value);
+               if (v == NULL)
+                       return NULL;
+               if (PyList_Append(tmp, v) != 0) {
+                       Py_DECREF(v);
+                       return NULL;
+               }
+               Py_DECREF(v);
+               return PyString_AsString(v);
+       }
+#endif
+       else {
+               PyObject *v = PyObject_Str(value);
+               if (v == NULL)
+                       return NULL;
+               if (PyList_Append(tmp, v) != 0) {
+                       Py_DECREF(v);
+                       return NULL;
+               }
+               Py_DECREF(v);
+               return PyString_AsString(v);
+       }
+}
+
+
+\f
+#define ARGSZ 64
+
+static char *
+Merge(PyObject *args)
+{
+       PyObject *tmp = NULL;
+       char *argvStore[ARGSZ];
+       char **argv = NULL;
+       int fvStore[ARGSZ];
+       int *fv = NULL;
+       int argc = 0, fvc = 0, i;
+       char *res = NULL;
+
+       if (!(tmp = PyList_New(0)))
+           return NULL;
+
+       argv = argvStore;
+       fv = fvStore;
+
+       if (args == NULL)
+               argc = 0;
+
+       else if (!PyTuple_Check(args)) {
+               argc = 1;
+               fv[0] = 0;
+               if (!(argv[0] = AsString(args, tmp)))
+                       goto finally;
+       }
+       else {
+               argc = PyTuple_Size(args);
+
+               if (argc > ARGSZ) {
+                       argv = (char **)ckalloc(argc * sizeof(char *));
+                       fv = (int *)ckalloc(argc * sizeof(int));
+                       if (argv == NULL || fv == NULL) {
+                               PyErr_NoMemory();
+                               goto finally;
+                       }
+               }
+
+               for (i = 0; i < argc; i++) {
+                       PyObject *v = PyTuple_GetItem(args, i);
+                       if (PyTuple_Check(v)) {
+                               fv[i] = 1;
+                               if (!(argv[i] = Merge(v)))
+                                       goto finally;
+                               fvc++;
+                       }
+                       else if (v == Py_None) {
+                               argc = i;
+                               break;
+                       }
+                       else {
+                               fv[i] = 0;
+                               if (!(argv[i] = AsString(v, tmp)))
+                                       goto finally;
+                               fvc++;
+                       }
+               }
+       }
+       res = Tcl_Merge(argc, argv);
+       if (res == NULL)
+               PyErr_SetString(Tkinter_TclError, "merge failed");
+
+  finally:
+       for (i = 0; i < fvc; i++)
+               if (fv[i]) {
+                       ckfree(argv[i]);
+               }
+       if (argv != argvStore)
+               ckfree(FREECAST argv);
+       if (fv != fvStore)
+               ckfree(FREECAST fv);
+
+       Py_DECREF(tmp);
+       return res;
+}
+
+
+\f
+static PyObject *
+Split(char *list)
+{
+       int argc;
+       char **argv;
+       PyObject *v;
+
+       if (list == NULL) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
+
+       if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
+               /* Not a list.
+                * Could be a quoted string containing funnies, e.g. {"}.
+                * Return the string itself.
+                */
+               return PyString_FromString(list);
+       }
+
+       if (argc == 0)
+               v = PyString_FromString("");
+       else if (argc == 1)
+               v = PyString_FromString(argv[0]);
+       else if ((v = PyTuple_New(argc)) != NULL) {
+               int i;
+               PyObject *w;
+
+               for (i = 0; i < argc; i++) {
+                       if ((w = Split(argv[i])) == NULL) {
+                               Py_DECREF(v);
+                               v = NULL;
+                               break;
+                       }
+                       PyTuple_SetItem(v, i, w);
+               }
+       }
+       Tcl_Free(FREECAST argv);
+       return v;
+}
+
+
+\f
+/**** Tkapp Object ****/
+
+#ifndef WITH_APPINIT
+int
+Tcl_AppInit(Tcl_Interp *interp)
+{
+       Tk_Window main;
+
+       main = Tk_MainWindow(interp);
+       if (Tcl_Init(interp) == TCL_ERROR) {
+               PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
+               return TCL_ERROR;
+       }
+       if (Tk_Init(interp) == TCL_ERROR) {
+               PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
+               return TCL_ERROR;
+       }
+       return TCL_OK;
+}
+#endif /* !WITH_APPINIT */
+
+
+\f
+
+/* Initialize the Tk application; see the `main' function in
+ * `tkMain.c'.
+ */
+
+static void EnableEventHook(void); /* Forward */
+static void DisableEventHook(void); /* Forward */
+
+static TkappObject *
+Tkapp_New(char *screenName, char *baseName, char *className, int interactive)
+{
+       TkappObject *v;
+       char *argv0;
+  
+       v = PyObject_New(TkappObject, &Tkapp_Type);
+       if (v == NULL)
+               return NULL;
+
+       v->interp = Tcl_CreateInterp();
+
+#if defined(macintosh)
+       /* This seems to be needed */
+       ClearMenuBar();
+       TkMacInitMenus(v->interp);
+#endif
+
+       /* Delete the 'exit' command, which can screw things up */
+       Tcl_DeleteCommand(v->interp, "exit");
+
+       if (screenName != NULL)
+               Tcl_SetVar2(v->interp, "env", "DISPLAY",
+                           screenName, TCL_GLOBAL_ONLY);
+
+       if (interactive)
+               Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
+       else
+               Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
+
+       /* This is used to get the application class for Tk 4.1 and up */
+       argv0 = (char*)ckalloc(strlen(className) + 1);
+       if (!argv0) {
+               PyErr_NoMemory();
+               Py_DECREF(v);
+               return NULL;
+       }
+
+       strcpy(argv0, className);
+       if (isupper((int)(argv0[0])))
+               argv0[0] = tolower(argv0[0]);
+       Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
+       ckfree(argv0);
+
+       if (Tcl_AppInit(v->interp) != TCL_OK)
+               return (TkappObject *)Tkinter_Error((PyObject *)v);
+
+       EnableEventHook();
+
+       return v;
+}
+
+
+\f
+/** Tcl Eval **/
+
+#if TKMAJORMINOR >= 8001
+#define USING_OBJECTS
+#endif
+
+#ifdef USING_OBJECTS
+
+static Tcl_Obj*
+AsObj(PyObject *value)
+{
+       Tcl_Obj *result;
+
+       if (PyString_Check(value))
+               return Tcl_NewStringObj(PyString_AS_STRING(value),
+                                       PyString_GET_SIZE(value));
+       else if (PyInt_Check(value))
+               return Tcl_NewLongObj(PyInt_AS_LONG(value));
+       else if (PyFloat_Check(value))
+               return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
+       else if (PyTuple_Check(value)) {
+               Tcl_Obj **argv = (Tcl_Obj**)
+                       ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
+               int i;
+               if(!argv)
+                 return 0;
+               for(i=0;i<PyTuple_Size(value);i++)
+                 argv[i] = AsObj(PyTuple_GetItem(value,i));
+               result = Tcl_NewListObj(PyTuple_Size(value), argv);
+               ckfree(FREECAST argv);
+               return result;
+       }
+#ifdef Py_USING_UNICODE
+       else if (PyUnicode_Check(value)) {
+#if TKMAJORMINOR <= 8001
+               /* In Tcl 8.1 we must use UTF-8 */
+               PyObject* utf8 = PyUnicode_AsUTF8String(value);
+               if (!utf8)
+                       return 0;
+               result = Tcl_NewStringObj(PyString_AS_STRING(utf8),
+                                         PyString_GET_SIZE(utf8));
+               Py_DECREF(utf8);
+               return result;
+#else /* TKMAJORMINOR > 8001 */
+               /* In Tcl 8.2 and later, use Tcl_NewUnicodeObj() */
+               if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
+                       /* XXX Should really test this at compile time */
+                       PyErr_SetString(PyExc_SystemError,
+                               "Py_UNICODE and Tcl_UniChar differ in size");
+                       return 0;
+               }
+               return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
+                                        PyUnicode_GET_SIZE(value));
+#endif /* TKMAJORMINOR > 8001 */
+       }
+#endif
+       else {
+               PyObject *v = PyObject_Str(value);
+               if (!v)
+                       return 0;
+               result = AsObj(v);
+               Py_DECREF(v);
+               return result;
+       }
+}
+
+static PyObject *
+Tkapp_Call(PyObject *self, PyObject *args)
+{
+       Tcl_Obj *objStore[ARGSZ];
+       Tcl_Obj **objv = NULL;
+       int objc = 0, i;
+       PyObject *res = NULL;
+       Tcl_Interp *interp = Tkapp_Interp(self);
+       /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
+       int flags = TCL_EVAL_DIRECT;
+
+       objv = objStore;
+
+       if (args == NULL)
+               /* do nothing */;
+
+       else if (!PyTuple_Check(args)) {
+               objv[0] = AsObj(args);
+               if (objv[0] == 0)
+                       goto finally;
+               objc = 1;
+               Tcl_IncrRefCount(objv[0]);
+       }
+       else {
+               objc = PyTuple_Size(args);
+
+               if (objc > ARGSZ) {
+                       objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
+                       if (objv == NULL) {
+                               PyErr_NoMemory();
+                               objc = 0;
+                               goto finally;
+                       }
+               }
+
+               for (i = 0; i < objc; i++) {
+                       PyObject *v = PyTuple_GetItem(args, i);
+                       if (v == Py_None) {
+                               objc = i;
+                               break;
+                       }
+                       objv[i] = AsObj(v);
+                       if (!objv[i]) {
+                               /* Reset objc, so it attempts to clear
+                                  objects only up to i. */
+                               objc = i;
+                               goto finally;
+                       }
+                       Tcl_IncrRefCount(objv[i]);
+               }
+       }
+
+       ENTER_TCL
+
+       i = Tcl_EvalObjv(interp, objc, objv, flags);
+
+       ENTER_OVERLAP
+       if (i == TCL_ERROR)
+               Tkinter_Error(self);
+       else {
+               /* We could request the object result here, but doing
+                  so would confuse applications that expect a string. */
+               char *s = Tcl_GetStringResult(interp);
+               char *p = s;
+
+               /* If the result contains any bytes with the top bit set,
+                  it's UTF-8 and we should decode it to Unicode */
+#ifdef Py_USING_UNICODE
+               while (*p != '\0') {
+                       if (*p & 0x80)
+                               break;
+                       p++;
+               }
+
+               if (*p == '\0')
+                       res = PyString_FromStringAndSize(s, (int)(p-s));
+               else {
+                       /* Convert UTF-8 to Unicode string */
+                       p = strchr(p, '\0');
+                       res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
+                       if (res == NULL) {
+                           PyErr_Clear();
+                           res = PyString_FromStringAndSize(s, (int)(p-s));
+                       }
+               }
+#else
+               p = strchr(p, '\0');
+               res = PyString_FromStringAndSize(s, (int)(p-s));
+#endif
+       }
+
+       LEAVE_OVERLAP_TCL
+
+  finally:
+       for (i = 0; i < objc; i++)
+               Tcl_DecrRefCount(objv[i]);
+       if (objv != objStore)
+               ckfree(FREECAST objv);
+       return res;
+}
+
+#else /* !USING_OBJECTS */
+
+static PyObject *
+Tkapp_Call(PyObject *self, PyObject *args)
+{
+       /* This is copied from Merge() */
+       PyObject *tmp = NULL;
+       char *argvStore[ARGSZ];
+       char **argv = NULL;
+       int fvStore[ARGSZ];
+       int *fv = NULL;
+       int argc = 0, fvc = 0, i;
+       PyObject *res = NULL; /* except this has a different type */
+       Tcl_CmdInfo info; /* and this is added */
+       Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
+
+       if (!(tmp = PyList_New(0)))
+           return NULL;
+
+       argv = argvStore;
+       fv = fvStore;
+
+       if (args == NULL)
+               argc = 0;
+
+       else if (!PyTuple_Check(args)) {
+               argc = 1;
+               fv[0] = 0;
+               if (!(argv[0] = AsString(args, tmp)))
+                       goto finally;
+       }
+       else {
+               argc = PyTuple_Size(args);
+
+               if (argc > ARGSZ) {
+                       argv = (char **)ckalloc(argc * sizeof(char *));
+                       fv = (int *)ckalloc(argc * sizeof(int));
+                       if (argv == NULL || fv == NULL) {
+                               PyErr_NoMemory();
+                               goto finally;
+                       }
+               }
+
+               for (i = 0; i < argc; i++) {
+                       PyObject *v = PyTuple_GetItem(args, i);
+                       if (PyTuple_Check(v)) {
+                               fv[i] = 1;
+                               if (!(argv[i] = Merge(v)))
+                                       goto finally;
+                               fvc++;
+                       }
+                       else if (v == Py_None) {
+                               argc = i;
+                               break;
+                       }
+                       else {
+                               fv[i] = 0;
+                               if (!(argv[i] = AsString(v, tmp)))
+                                       goto finally;
+                               fvc++;
+                       }
+               }
+       }
+       /* End code copied from Merge() */
+
+       /* All this to avoid a call to Tcl_Merge() and the corresponding call
+          to Tcl_SplitList() inside Tcl_Eval()...  It can save a bundle! */
+       if (Py_VerboseFlag >= 2) {
+               for (i = 0; i < argc; i++)
+                       PySys_WriteStderr("%s ", argv[i]);
+       }
+       ENTER_TCL
+       info.proc = NULL;
+       if (argc < 1 ||
+           !Tcl_GetCommandInfo(interp, argv[0], &info) ||
+           info.proc == NULL)
+       {
+               char *cmd;
+               cmd = Tcl_Merge(argc, argv);
+               i = Tcl_Eval(interp, cmd);
+               ckfree(cmd);
+       }
+       else {
+               Tcl_ResetResult(interp);
+               i = (*info.proc)(info.clientData, interp, argc, argv);
+       }
+       ENTER_OVERLAP
+       if (info.proc == NULL && Py_VerboseFlag >= 2)
+               PySys_WriteStderr("... use TclEval ");
+       if (i == TCL_ERROR) {
+               if (Py_VerboseFlag >= 2)
+                       PySys_WriteStderr("... error: '%s'\n",
+                               Tcl_GetStringResult(interp));
+               Tkinter_Error(self);
+       }
+       else {
+               if (Py_VerboseFlag >= 2)
+                       PySys_WriteStderr("-> '%s'\n", Tcl_GetStringResult(interp));
+               res = PyString_FromString(Tcl_GetStringResult(interp));
+       }
+       LEAVE_OVERLAP_TCL
+
+       /* Copied from Merge() again */
+  finally:
+       for (i = 0; i < fvc; i++)
+               if (fv[i]) {
+                       ckfree(argv[i]);
+               }
+       if (argv != argvStore)
+               ckfree(FREECAST argv);
+       if (fv != fvStore)
+               ckfree(FREECAST fv);
+
+       Py_DECREF(tmp);
+       return res;
+}
+
+#endif /* !USING_OBJECTS */
+
+static PyObject *
+Tkapp_GlobalCall(PyObject *self, PyObject *args)
+{
+       /* Could do the same here as for Tkapp_Call(), but this is not used
+          much, so I can't be bothered.  Unfortunately Tcl doesn't export a
+          way for the user to do what all its Global* variants do (save and
+          reset the scope pointer, call the local version, restore the saved
+          scope pointer). */
+
+       char *cmd;
+       PyObject *res = NULL;
+
+       cmd  = Merge(args);
+       if (cmd) {
+               int err;
+               ENTER_TCL
+               err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
+               ENTER_OVERLAP
+               if (err == TCL_ERROR)
+                       res = Tkinter_Error(self);
+               else
+                       res = PyString_FromString(Tkapp_Result(self));
+               LEAVE_OVERLAP_TCL
+               ckfree(cmd);
+       }
+
+       return res;
+}
+
+static PyObject *
+Tkapp_Eval(PyObject *self, PyObject *args)
+{
+       char *script;
+       PyObject *res = NULL;
+       int err;
+  
+       if (!PyArg_ParseTuple(args, "s:eval", &script))
+               return NULL;
+
+       ENTER_TCL
+       err = Tcl_Eval(Tkapp_Interp(self), script);
+       ENTER_OVERLAP
+       if (err == TCL_ERROR)
+               res = Tkinter_Error(self);
+       else
+               res = PyString_FromString(Tkapp_Result(self));
+       LEAVE_OVERLAP_TCL
+       return res;
+}
+
+static PyObject *
+Tkapp_GlobalEval(PyObject *self, PyObject *args)
+{
+       char *script;
+       PyObject *res = NULL;
+       int err;
+
+       if (!PyArg_ParseTuple(args, "s:globaleval", &script))
+               return NULL;
+
+       ENTER_TCL
+       err = Tcl_GlobalEval(Tkapp_Interp(self), script);
+       ENTER_OVERLAP
+       if (err == TCL_ERROR)
+               res = Tkinter_Error(self);
+       else
+               res = PyString_FromString(Tkapp_Result(self));
+       LEAVE_OVERLAP_TCL
+       return res;
+}
+
+static PyObject *
+Tkapp_EvalFile(PyObject *self, PyObject *args)
+{
+       char *fileName;
+       PyObject *res = NULL;
+       int err;
+
+       if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
+               return NULL;
+
+       ENTER_TCL
+       err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
+       ENTER_OVERLAP
+       if (err == TCL_ERROR)
+               res = Tkinter_Error(self);
+
+       else
+               res = PyString_FromString(Tkapp_Result(self));
+       LEAVE_OVERLAP_TCL
+       return res;
+}
+
+static PyObject *
+Tkapp_Record(PyObject *self, PyObject *args)
+{
+       char *script;
+       PyObject *res = NULL;
+       int err;
+
+       if (!PyArg_ParseTuple(args, "s", &script))
+               return NULL;
+
+       ENTER_TCL
+       err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
+       ENTER_OVERLAP
+       if (err == TCL_ERROR)
+               res = Tkinter_Error(self);
+       else
+               res = PyString_FromString(Tkapp_Result(self));
+       LEAVE_OVERLAP_TCL
+       return res;
+}
+
+static PyObject *
+Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
+{
+       char *msg;
+
+       if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
+               return NULL;
+       ENTER_TCL
+       Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
+       LEAVE_TCL
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+
+\f
+/** Tcl Variable **/
+
+static PyObject *
+SetVar(PyObject *self, PyObject *args, int flags)
+{
+       char *name1, *name2, *ok, *s;
+       PyObject *newValue;
+       PyObject *tmp;
+
+       tmp = PyList_New(0);
+       if (!tmp)
+               return NULL;
+
+       if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
+               /* XXX Merge? */
+               s = AsString(newValue, tmp);
+               if (s == NULL)
+                       return NULL;
+               ENTER_TCL
+               ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
+               LEAVE_TCL
+       }
+       else {
+               PyErr_Clear();
+               if (PyArg_ParseTuple(args, "ssO:setvar",
+                                    &name1, &name2, &newValue)) {
+                       s = AsString(newValue, tmp);
+                       if (s == NULL)
+                               return NULL;
+                       ENTER_TCL
+                       ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2, 
+                                        s, flags);
+                       LEAVE_TCL
+               }
+               else {
+                       Py_DECREF(tmp);
+                       return NULL;
+               }
+       }
+       Py_DECREF(tmp);
+
+       if (!ok)
+               return Tkinter_Error(self);
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *
+Tkapp_SetVar(PyObject *self, PyObject *args)
+{
+       return SetVar(self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
+{
+       return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+
+\f
+static PyObject *
+GetVar(PyObject *self, PyObject *args, int flags)
+{
+       char *name1, *name2=NULL, *s;
+       PyObject *res = NULL;
+
+       if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
+               return NULL;
+       ENTER_TCL
+       if (name2 == NULL)
+               s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
+
+       else
+               s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
+       ENTER_OVERLAP
+
+       if (s == NULL)
+               res = Tkinter_Error(self);
+       else
+               res = PyString_FromString(s);
+       LEAVE_OVERLAP_TCL
+       return res;
+}
+
+static PyObject *
+Tkapp_GetVar(PyObject *self, PyObject *args)
+{
+       return GetVar(self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
+{
+       return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+
+\f
+static PyObject *
+UnsetVar(PyObject *self, PyObject *args, int flags)
+{
+       char *name1, *name2=NULL;
+       PyObject *res = NULL;
+       int code;
+
+       if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
+               return NULL;
+       ENTER_TCL
+       if (name2 == NULL)
+               code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
+
+       else
+               code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
+       ENTER_OVERLAP
+
+       if (code == TCL_ERROR)
+               res = Tkinter_Error(self);
+       else {
+               Py_INCREF(Py_None);
+               res = Py_None;
+       }
+       LEAVE_OVERLAP_TCL
+       return res;
+}
+
+static PyObject *
+Tkapp_UnsetVar(PyObject *self, PyObject *args)
+{
+       return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
+{
+       return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+
+\f
+/** Tcl to Python **/
+
+static PyObject *
+Tkapp_GetInt(PyObject *self, PyObject *args)
+{
+       char *s;
+       int v;
+
+       if (!PyArg_ParseTuple(args, "s:getint", &s))
+               return NULL;
+       if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
+               return Tkinter_Error(self);
+       return Py_BuildValue("i", v);
+}
+
+static PyObject *
+Tkapp_GetDouble(PyObject *self, PyObject *args)
+{
+       char *s;
+       double v;
+
+       if (!PyArg_ParseTuple(args, "s:getdouble", &s))
+               return NULL;
+       if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
+               return Tkinter_Error(self);
+       return Py_BuildValue("d", v);
+}
+
+static PyObject *
+Tkapp_GetBoolean(PyObject *self, PyObject *args)
+{
+       char *s;
+       int v;
+
+       if (!PyArg_ParseTuple(args, "s:getboolean", &s))
+               return NULL;
+       if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
+               return Tkinter_Error(self);
+       return Py_BuildValue("i", v);
+}
+
+static PyObject *
+Tkapp_ExprString(PyObject *self, PyObject *args)
+{
+       char *s;
+       PyObject *res = NULL;
+       int retval;
+
+       if (!PyArg_ParseTuple(args, "s:exprstring", &s))
+               return NULL;
+       ENTER_TCL
+       retval = Tcl_ExprString(Tkapp_Interp(self), s);
+       ENTER_OVERLAP
+       if (retval == TCL_ERROR)
+               res = Tkinter_Error(self);
+       else
+               res = Py_BuildValue("s", Tkapp_Result(self));
+       LEAVE_OVERLAP_TCL
+       return res;
+}
+
+static PyObject *
+Tkapp_ExprLong(PyObject *self, PyObject *args)
+{
+       char *s;
+       PyObject *res = NULL;
+       int retval;
+       long v;
+
+       if (!PyArg_ParseTuple(args, "s:exprlong", &s))
+               return NULL;
+       ENTER_TCL
+       retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
+       ENTER_OVERLAP
+       if (retval == TCL_ERROR)
+               res = Tkinter_Error(self);
+       else
+               res = Py_BuildValue("l", v);
+       LEAVE_OVERLAP_TCL
+       return res;
+}
+
+static PyObject *
+Tkapp_ExprDouble(PyObject *self, PyObject *args)
+{
+       char *s;
+       PyObject *res = NULL;
+       double v;
+       int retval;
+
+       if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
+               return NULL;
+       PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
+       ENTER_TCL
+       retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
+       ENTER_OVERLAP
+       PyFPE_END_PROTECT(retval)
+       if (retval == TCL_ERROR)
+               res = Tkinter_Error(self);
+       else
+               res = Py_BuildValue("d", v);
+       LEAVE_OVERLAP_TCL
+       return res;
+}
+
+static PyObject *
+Tkapp_ExprBoolean(PyObject *self, PyObject *args)
+{
+       char *s;
+       PyObject *res = NULL;
+       int retval;
+       int v;
+
+       if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
+               return NULL;
+       ENTER_TCL
+       retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
+       ENTER_OVERLAP
+       if (retval == TCL_ERROR)
+               res = Tkinter_Error(self);
+       else
+               res = Py_BuildValue("i", v);
+       LEAVE_OVERLAP_TCL
+       return res;
+}
+
+
+\f
+static PyObject *
+Tkapp_SplitList(PyObject *self, PyObject *args)
+{
+       char *list;
+       int argc;
+       char **argv;
+       PyObject *v;
+       int i;
+
+       if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
+               return NULL;
+
+       if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
+               return Tkinter_Error(self);
+
+       if (!(v = PyTuple_New(argc)))
+               return NULL;
+       
+       for (i = 0; i < argc; i++) {
+               PyObject *s = PyString_FromString(argv[i]);
+               if (!s || PyTuple_SetItem(v, i, s)) {
+                       Py_DECREF(v);
+                       v = NULL;
+                       goto finally;
+               }
+       }
+
+  finally:
+       ckfree(FREECAST argv);
+       return v;
+}
+
+static PyObject *
+Tkapp_Split(PyObject *self, PyObject *args)
+{
+       char *list;
+
+       if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
+               return NULL;
+       return Split(list);
+}
+
+static PyObject *
+Tkapp_Merge(PyObject *self, PyObject *args)
+{
+       char *s = Merge(args);
+       PyObject *res = NULL;
+
+       if (s) {
+               res = PyString_FromString(s);
+               ckfree(s);
+       }
+
+       return res;
+}
+
+
+\f
+/** Tcl Command **/
+
+/* Client data struct */
+typedef struct {
+       PyObject *self;
+       PyObject *func;
+} PythonCmd_ClientData;
+
+static int
+PythonCmd_Error(Tcl_Interp *interp)
+{
+       errorInCmd = 1;
+       PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
+       LEAVE_PYTHON
+       return TCL_ERROR;
+}
+
+/* This is the Tcl command that acts as a wrapper for Python
+ * function or method.
+ */
+static int
+PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
+{
+       PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
+       PyObject *self, *func, *arg, *res, *tmp;
+       int i, rv;
+       char *s;
+
+       ENTER_PYTHON
+
+       /* TBD: no error checking here since we know, via the
+        * Tkapp_CreateCommand() that the client data is a two-tuple
+        */
+       self = data->self;
+       func = data->func;
+
+       /* Create argument list (argv1, ..., argvN) */
+       if (!(arg = PyTuple_New(argc - 1)))
+               return PythonCmd_Error(interp);
+
+       for (i = 0; i < (argc - 1); i++) {
+               PyObject *s = PyString_FromString(argv[i + 1]);
+               if (!s || PyTuple_SetItem(arg, i, s)) {
+                       Py_DECREF(arg);
+                       return PythonCmd_Error(interp);
+               }
+       }
+       res = PyEval_CallObject(func, arg);
+       Py_DECREF(arg);
+
+       if (res == NULL)
+               return PythonCmd_Error(interp);
+
+       if (!(tmp = PyList_New(0))) {
+               Py_DECREF(res);
+               return PythonCmd_Error(interp);
+       }
+
+       s = AsString(res, tmp);
+       if (s == NULL) {
+               rv = PythonCmd_Error(interp);
+       }
+       else {
+               Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
+               rv = TCL_OK;
+       }
+
+       Py_DECREF(res);
+       Py_DECREF(tmp);
+
+       LEAVE_PYTHON
+
+       return rv;
+}
+
+static void
+PythonCmdDelete(ClientData clientData)
+{
+       PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
+
+       ENTER_PYTHON
+       Py_XDECREF(data->self);
+       Py_XDECREF(data->func);
+       PyMem_DEL(data);
+       LEAVE_PYTHON
+}
+
+
+\f
+static PyObject *
+Tkapp_CreateCommand(PyObject *self, PyObject *args)
+{
+       PythonCmd_ClientData *data;
+       char *cmdName;
+       PyObject *func;
+       Tcl_Command err;
+
+       if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
+               return NULL;
+       if (!PyCallable_Check(func)) {
+               PyErr_SetString(PyExc_TypeError, "command not callable");
+               return NULL;
+       }
+
+       data = PyMem_NEW(PythonCmd_ClientData, 1);
+       if (!data)
+               return NULL;
+       Py_XINCREF(self);
+       Py_XINCREF(func);
+       data->self = self;
+       data->func = func;
+
+       ENTER_TCL
+       err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
+                               (ClientData)data, PythonCmdDelete);
+       LEAVE_TCL
+       if (err == NULL) {
+               PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
+               PyMem_DEL(data);
+               return NULL;
+       }
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+
+\f
+static PyObject *
+Tkapp_DeleteCommand(PyObject *self, PyObject *args)
+{
+       char *cmdName;
+       int err;
+
+       if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
+               return NULL;
+       ENTER_TCL
+       err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
+       LEAVE_TCL
+       if (err == -1) {
+               PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
+               return NULL;
+       }
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+
+\f
+#ifdef HAVE_CREATEFILEHANDLER
+/** File Handler **/
+
+typedef struct _fhcdata {
+       PyObject *func;
+       PyObject *file;
+       int id;
+       struct _fhcdata *next;
+} FileHandler_ClientData;
+
+static FileHandler_ClientData *HeadFHCD;
+
+static FileHandler_ClientData *
+NewFHCD(PyObject *func, PyObject *file, int id)
+{
+       FileHandler_ClientData *p;
+       p = PyMem_NEW(FileHandler_ClientData, 1);
+       if (p != NULL) {
+               Py_XINCREF(func);
+               Py_XINCREF(file);
+               p->func = func;
+               p->file = file;
+               p->id = id;
+               p->next = HeadFHCD;
+               HeadFHCD = p;
+       }
+       return p;
+}
+
+static void
+DeleteFHCD(int id)
+{
+       FileHandler_ClientData *p, **pp;
+       
+       pp = &HeadFHCD; 
+       while ((p = *pp) != NULL) {
+               if (p->id == id) {
+                       *pp = p->next;
+                       Py_XDECREF(p->func);
+                       Py_XDECREF(p->file);
+                       PyMem_DEL(p);
+               }
+               else
+                       pp = &p->next;
+       }
+}
+
+static void
+FileHandler(ClientData clientData, int mask)
+{
+       FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
+       PyObject *func, *file, *arg, *res;
+
+       ENTER_PYTHON
+       func = data->func;
+       file = data->file;
+
+       arg = Py_BuildValue("(Oi)", file, (long) mask);
+       res = PyEval_CallObject(func, arg);
+       Py_DECREF(arg);
+
+       if (res == NULL) {
+               errorInCmd = 1;
+               PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
+       }
+       Py_XDECREF(res);
+       LEAVE_PYTHON
+}
+
+static PyObject *
+Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
+     /* args is (file, mask, func) */
+{
+       FileHandler_ClientData *data;
+       PyObject *file, *func;
+       int mask, tfile;
+
+       if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
+                             &file, &mask, &func))
+               return NULL;
+       tfile = PyObject_AsFileDescriptor(file);
+       if (tfile < 0)
+               return NULL;
+       if (!PyCallable_Check(func)) {
+               PyErr_SetString(PyExc_TypeError, "bad argument list");
+               return NULL;
+       }
+
+       data = NewFHCD(func, file, tfile);
+       if (data == NULL)
+               return NULL;
+
+       /* Ought to check for null Tcl_File object... */
+       ENTER_TCL
+       Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
+       LEAVE_TCL
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *
+Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
+{
+       PyObject *file;
+       int tfile;
+  
+       if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
+               return NULL;
+       tfile = PyObject_AsFileDescriptor(file);
+       if (tfile < 0)
+               return NULL;
+
+       DeleteFHCD(tfile);
+
+       /* Ought to check for null Tcl_File object... */
+       ENTER_TCL
+       Tcl_DeleteFileHandler(tfile);
+       LEAVE_TCL
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+#endif /* HAVE_CREATEFILEHANDLER */
+
+\f
+/**** Tktt Object (timer token) ****/
+
+staticforward PyTypeObject Tktt_Type;
+
+typedef struct {
+       PyObject_HEAD
+       Tcl_TimerToken token;
+       PyObject *func;
+} TkttObject;
+
+static PyObject *
+Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
+{
+       TkttObject *v = (TkttObject *)self;
+       PyObject *func = v->func;
+
+       if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
+               return NULL;
+       if (v->token != NULL) {
+               Tcl_DeleteTimerHandler(v->token);
+               v->token = NULL;
+       }
+       if (func != NULL) {
+               v->func = NULL;
+               Py_DECREF(func);
+               Py_DECREF(v); /* See Tktt_New() */
+       }
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyMethodDef Tktt_methods[] =
+{
+       {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
+       {NULL, NULL}
+};
+
+static TkttObject *
+Tktt_New(PyObject *func)
+{
+       TkttObject *v;
+  
+       v = PyObject_New(TkttObject, &Tktt_Type);
+       if (v == NULL)
+               return NULL;
+
+       Py_INCREF(func);
+       v->token = NULL;
+       v->func = func;
+
+       /* Extra reference, deleted when called or when handler is deleted */
+       Py_INCREF(v);
+       return v;
+}
+
+static void
+Tktt_Dealloc(PyObject *self)
+{
+       TkttObject *v = (TkttObject *)self;
+       PyObject *func = v->func;
+
+       Py_XDECREF(func);
+
+       PyObject_Del(self);
+}
+
+static PyObject *
+Tktt_Repr(PyObject *self)
+{
+       TkttObject *v = (TkttObject *)self;
+       char buf[100];
+
+       PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
+                       v->func == NULL ? ", handler deleted" : "");
+       return PyString_FromString(buf);
+}
+
+static PyObject *
+Tktt_GetAttr(PyObject *self, char *name)
+{
+       return Py_FindMethod(Tktt_methods, self, name);
+}
+
+static PyTypeObject Tktt_Type =
+{
+       PyObject_HEAD_INIT(NULL)
+       0,                                   /*ob_size */
+       "tktimertoken",                      /*tp_name */
+       sizeof(TkttObject),                  /*tp_basicsize */
+       0,                                   /*tp_itemsize */
+       Tktt_Dealloc,                        /*tp_dealloc */
+       0,                                   /*tp_print */
+       Tktt_GetAttr,                        /*tp_getattr */
+       0,                                   /*tp_setattr */
+       0,                                   /*tp_compare */
+       Tktt_Repr,                           /*tp_repr */
+       0,                                   /*tp_as_number */
+       0,                                   /*tp_as_sequence */
+       0,                                   /*tp_as_mapping */
+       0,                                   /*tp_hash */
+};
+
+
+\f
+/** Timer Handler **/
+
+static void
+TimerHandler(ClientData clientData)
+{
+       TkttObject *v = (TkttObject *)clientData;
+       PyObject *func = v->func;
+       PyObject *res;
+
+       if (func == NULL)
+               return;
+
+       v->func = NULL;
+
+       ENTER_PYTHON
+
+       res  = PyEval_CallObject(func, NULL);
+       Py_DECREF(func);
+       Py_DECREF(v); /* See Tktt_New() */
+
+       if (res == NULL) {
+               errorInCmd = 1;
+               PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
+       }
+       else
+               Py_DECREF(res);
+
+       LEAVE_PYTHON
+}
+
+static PyObject *
+Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
+{
+       int milliseconds;
+       PyObject *func;
+       TkttObject *v;
+
+       if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
+                             &milliseconds, &func))
+               return NULL;
+       if (!PyCallable_Check(func)) {
+               PyErr_SetString(PyExc_TypeError, "bad argument list");
+               return NULL;
+       }
+       v = Tktt_New(func);
+       v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
+                                         (ClientData)v);
+
+       return (PyObject *) v;
+}
+
+\f
+/** Event Loop **/
+
+static PyObject *
+Tkapp_MainLoop(PyObject *self, PyObject *args)
+{
+       int threshold = 0;
+#ifdef WITH_THREAD
+       PyThreadState *tstate = PyThreadState_Get();
+#endif
+
+       if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
+               return NULL;
+
+       quitMainLoop = 0;
+       while (Tk_GetNumMainWindows() > threshold &&
+              !quitMainLoop &&
+              !errorInCmd)
+       {
+               int result;
+
+#ifdef WITH_THREAD
+               Py_BEGIN_ALLOW_THREADS
+               PyThread_acquire_lock(tcl_lock, 1);
+               tcl_tstate = tstate;
+               result = Tcl_DoOneEvent(TCL_DONT_WAIT);
+               tcl_tstate = NULL;
+               PyThread_release_lock(tcl_lock);
+               if (result == 0)
+                       Sleep(20);
+               Py_END_ALLOW_THREADS
+#else
+               result = Tcl_DoOneEvent(0);
+#endif
+
+               if (PyErr_CheckSignals() != 0)
+                       return NULL;
+               if (result < 0)
+                       break;
+       }
+       quitMainLoop = 0;
+
+       if (errorInCmd) {
+               errorInCmd = 0;
+               PyErr_Restore(excInCmd, valInCmd, trbInCmd);
+               excInCmd = valInCmd = trbInCmd = NULL;
+               return NULL;
+       }
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *
+Tkapp_DoOneEvent(PyObject *self, PyObject *args)
+{
+       int flags = 0;
+       int rv;
+
+       if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
+               return NULL;
+
+       ENTER_TCL
+       rv = Tcl_DoOneEvent(flags);
+       LEAVE_TCL
+       return Py_BuildValue("i", rv);
+}
+
+static PyObject *
+Tkapp_Quit(PyObject *self, PyObject *args)
+{
+
+       if (!PyArg_ParseTuple(args, ":quit"))
+               return NULL;
+
+       quitMainLoop = 1;
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *
+Tkapp_InterpAddr(PyObject *self, PyObject *args)
+{
+
+       if (!PyArg_ParseTuple(args, ":interpaddr"))
+               return NULL;
+
+       return PyInt_FromLong((long)Tkapp_Interp(self));
+}
+
+
+\f
+/**** Tkapp Method List ****/
+
+static PyMethodDef Tkapp_methods[] =
+{
+       {"call",               Tkapp_Call, 0},
+       {"globalcall",         Tkapp_GlobalCall, 0},
+       {"eval",               Tkapp_Eval, 1},
+       {"globaleval",         Tkapp_GlobalEval, 1},
+       {"evalfile",           Tkapp_EvalFile, 1},
+       {"record",             Tkapp_Record, 1},
+       {"adderrorinfo",       Tkapp_AddErrorInfo, 1},
+       {"setvar",             Tkapp_SetVar, 1},
+       {"globalsetvar",       Tkapp_GlobalSetVar, 1},
+       {"getvar",             Tkapp_GetVar, 1},
+       {"globalgetvar",       Tkapp_GlobalGetVar, 1},
+       {"unsetvar",           Tkapp_UnsetVar, 1},
+       {"globalunsetvar",     Tkapp_GlobalUnsetVar, 1},
+       {"getint",             Tkapp_GetInt, 1},
+       {"getdouble",          Tkapp_GetDouble, 1},
+       {"getboolean",         Tkapp_GetBoolean, 1},
+       {"exprstring",         Tkapp_ExprString, 1},
+       {"exprlong",           Tkapp_ExprLong, 1},
+       {"exprdouble",         Tkapp_ExprDouble, 1},
+       {"exprboolean",        Tkapp_ExprBoolean, 1},
+       {"splitlist",          Tkapp_SplitList, 1},
+       {"split",              Tkapp_Split, 1},
+       {"merge",              Tkapp_Merge, 0},
+       {"createcommand",      Tkapp_CreateCommand, 1},
+       {"deletecommand",      Tkapp_DeleteCommand, 1},
+#ifdef HAVE_CREATEFILEHANDLER
+       {"createfilehandler",  Tkapp_CreateFileHandler, 1},
+       {"deletefilehandler",  Tkapp_DeleteFileHandler, 1},
+#endif
+       {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
+       {"mainloop",           Tkapp_MainLoop, 1},
+       {"dooneevent",         Tkapp_DoOneEvent, 1},
+       {"quit",               Tkapp_Quit, 1},
+       {"interpaddr",         Tkapp_InterpAddr, 1},
+       {NULL,                 NULL}
+};
+
+
+\f
+/**** Tkapp Type Methods ****/
+
+static void
+Tkapp_Dealloc(PyObject *self)
+{
+       ENTER_TCL
+       Tcl_DeleteInterp(Tkapp_Interp(self));
+       LEAVE_TCL
+       PyObject_Del(self);
+       DisableEventHook();
+}
+
+static PyObject *
+Tkapp_GetAttr(PyObject *self, char *name)
+{
+       return Py_FindMethod(Tkapp_methods, self, name);
+}
+
+static PyTypeObject Tkapp_Type =
+{
+       PyObject_HEAD_INIT(NULL)
+       0,                                   /*ob_size */
+       "tkapp",                             /*tp_name */
+       sizeof(TkappObject),                 /*tp_basicsize */
+       0,                                   /*tp_itemsize */
+       Tkapp_Dealloc,                       /*tp_dealloc */
+       0,                                   /*tp_print */
+       Tkapp_GetAttr,                       /*tp_getattr */
+       0,                                   /*tp_setattr */
+       0,                                   /*tp_compare */
+       0,                                   /*tp_repr */
+       0,                                   /*tp_as_number */
+       0,                                   /*tp_as_sequence */
+       0,                                   /*tp_as_mapping */
+       0,                                   /*tp_hash */
+};
+
+
+\f
+/**** Tkinter Module ****/
+
+typedef struct {
+       PyObject* tuple;
+       int size; /* current size */
+       int maxsize; /* allocated size */
+} FlattenContext;
+
+static int
+_bump(FlattenContext* context, int size)
+{
+       /* expand tuple to hold (at least) size new items.
+          return true if successful, false if an exception was raised */
+
+       int maxsize = context->maxsize * 2;
+
+       if (maxsize < context->size + size)
+               maxsize = context->size + size;
+
+       context->maxsize = maxsize;
+
+       return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
+}
+
+static int
+_flatten1(FlattenContext* context, PyObject* item, int depth)
+{
+       /* add tuple or list to argument tuple (recursively) */
+
+       int i, size;
+
+       if (depth > 1000) {
+               PyErr_SetString(PyExc_ValueError,
+                               "nesting too deep in _flatten");
+               return 0;
+       } else if (PyList_Check(item)) {
+               size = PyList_GET_SIZE(item);
+               /* preallocate (assume no nesting) */
+               if (context->size + size > context->maxsize &&
+                   !_bump(context, size))
+                       return 0;
+               /* copy items to output tuple */
+               for (i = 0; i < size; i++) {
+                       PyObject *o = PyList_GET_ITEM(item, i);
+                       if (PyList_Check(o) || PyTuple_Check(o)) {
+                               if (!_flatten1(context, o, depth + 1))
+                                       return 0;
+                       } else if (o != Py_None) {
+                               if (context->size + 1 > context->maxsize &&
+                                   !_bump(context, 1))
+                                       return 0;
+                               Py_INCREF(o);
+                               PyTuple_SET_ITEM(context->tuple,
+                                                context->size++, o);
+                       }
+               }
+       } else if (PyTuple_Check(item)) {
+               /* same, for tuples */
+               size = PyTuple_GET_SIZE(item);
+               if (context->size + size > context->maxsize &&
+                   !_bump(context, size))
+                       return 0;
+               for (i = 0; i < size; i++) {
+                       PyObject *o = PyTuple_GET_ITEM(item, i);
+                       if (PyList_Check(o) || PyTuple_Check(o)) {
+                               if (!_flatten1(context, o, depth + 1))
+                                       return 0;
+                       } else if (o != Py_None) {
+                               if (context->size + 1 > context->maxsize &&
+                                   !_bump(context, 1))
+                                       return 0;
+                               Py_INCREF(o);
+                               PyTuple_SET_ITEM(context->tuple,
+                                                context->size++, o);
+                       }
+               }
+       } else {
+               PyErr_SetString(PyExc_TypeError, "argument must be sequence");
+               return 0;
+       }
+       return 1;
+}
+
+static PyObject *
+Tkinter_Flatten(PyObject* self, PyObject* args)
+{
+       FlattenContext context;
+       PyObject* item;
+
+       if (!PyArg_ParseTuple(args, "O:_flatten", &item))
+               return NULL;
+
+       context.maxsize = PySequence_Size(item);
+       if (context.maxsize <= 0)
+               return PyTuple_New(0);
+       
+       context.tuple = PyTuple_New(context.maxsize);
+       if (!context.tuple)
+               return NULL;
+       
+       context.size = 0;
+
+       if (!_flatten1(&context, item,0))
+               return NULL;
+
+       if (_PyTuple_Resize(&context.tuple, context.size))
+               return NULL;
+
+       return context.tuple;
+}
+
+static PyObject *
+Tkinter_Create(PyObject *self, PyObject *args)
+{
+       char *screenName = NULL;
+       char *baseName = NULL;
+       char *className = NULL;
+       int interactive = 0;
+
+       baseName = strrchr(Py_GetProgramName(), '/');
+       if (baseName != NULL)
+               baseName++;
+       else
+               baseName = Py_GetProgramName();
+       className = "Tk";
+  
+       if (!PyArg_ParseTuple(args, "|zssi:create",
+                             &screenName, &baseName, &className,
+                             &interactive))
+               return NULL;
+
+       return (PyObject *) Tkapp_New(screenName, baseName, className, 
+                                     interactive);
+}
+
+static PyMethodDef moduleMethods[] =
+{
+       {"_flatten",           Tkinter_Flatten, 1},
+       {"create",             Tkinter_Create, 1},
+#ifdef HAVE_CREATEFILEHANDLER
+       {"createfilehandler",  Tkapp_CreateFileHandler, 1},
+       {"deletefilehandler",  Tkapp_DeleteFileHandler, 1},
+#endif
+       {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
+       {"mainloop",           Tkapp_MainLoop, 1},
+       {"dooneevent",         Tkapp_DoOneEvent, 1},
+       {"quit",               Tkapp_Quit, 1},
+       {NULL,                 NULL}
+};
+
+#ifdef WAIT_FOR_STDIN
+
+static int stdin_ready = 0;
+
+#ifndef MS_WINDOWS
+static void
+MyFileProc(void *clientData, int mask)
+{
+       stdin_ready = 1;
+}
+#endif
+
+static PyThreadState *event_tstate = NULL;
+
+static int
+EventHook(void)
+{
+#ifndef MS_WINDOWS
+       int tfile;
+#endif
+#ifdef WITH_THREAD
+       PyEval_RestoreThread(event_tstate);
+#endif
+       stdin_ready = 0;
+       errorInCmd = 0;
+#ifndef MS_WINDOWS
+       tfile = fileno(stdin);
+       Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
+#endif
+       while (!errorInCmd && !stdin_ready) {
+               int result;
+#ifdef MS_WINDOWS
+               if (_kbhit()) {
+                       stdin_ready = 1;
+                       break;
+               }
+#endif
+#if defined(WITH_THREAD) || defined(MS_WINDOWS)
+               Py_BEGIN_ALLOW_THREADS
+               PyThread_acquire_lock(tcl_lock, 1);
+               tcl_tstate = event_tstate;
+
+               result = Tcl_DoOneEvent(TCL_DONT_WAIT);
+
+               tcl_tstate = NULL;
+               PyThread_release_lock(tcl_lock);
+               if (result == 0)
+                       Sleep(20);
+               Py_END_ALLOW_THREADS
+#else
+               result = Tcl_DoOneEvent(0);
+#endif
+
+               if (result < 0)
+                       break;
+       }
+#ifndef MS_WINDOWS
+       Tcl_DeleteFileHandler(tfile);
+#endif
+       if (errorInCmd) {
+               errorInCmd = 0;
+               PyErr_Restore(excInCmd, valInCmd, trbInCmd);
+               excInCmd = valInCmd = trbInCmd = NULL;
+               PyErr_Print();
+       }
+#ifdef WITH_THREAD
+       PyEval_SaveThread();
+#endif
+       return 0;
+}
+
+#endif
+
+static void
+EnableEventHook(void)
+{
+#ifdef WAIT_FOR_STDIN
+       if (PyOS_InputHook == NULL) {
+#ifdef WITH_THREAD
+               event_tstate = PyThreadState_Get();
+#endif
+               PyOS_InputHook = EventHook;
+       }
+#endif
+}
+
+static void
+DisableEventHook(void)
+{
+#ifdef WAIT_FOR_STDIN
+       if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
+               PyOS_InputHook = NULL;
+       }
+#endif
+}
+
+
+/* all errors will be checked in one fell swoop in init_tkinter() */
+static void
+ins_long(PyObject *d, char *name, long val)
+{
+       PyObject *v = PyInt_FromLong(val);
+       if (v) {
+               PyDict_SetItemString(d, name, v);
+               Py_DECREF(v);
+       }
+}
+static void
+ins_string(PyObject *d, char *name, char *val)
+{
+       PyObject *v = PyString_FromString(val);
+       if (v) {
+               PyDict_SetItemString(d, name, v);
+               Py_DECREF(v);
+       }
+}
+
+
+DL_EXPORT(void)
+init_tkinter(void)
+{
+       PyObject *m, *d;
+
+       Tkapp_Type.ob_type = &PyType_Type;
+
+#ifdef WITH_THREAD
+       tcl_lock = PyThread_allocate_lock();
+#endif
+
+       m = Py_InitModule("_tkinter", moduleMethods);
+
+       d = PyModule_GetDict(m);
+       Tkinter_TclError = Py_BuildValue("s", "TclError");
+       PyDict_SetItemString(d, "TclError", Tkinter_TclError);
+
+       ins_long(d, "READABLE", TCL_READABLE);
+       ins_long(d, "WRITABLE", TCL_WRITABLE);
+       ins_long(d, "EXCEPTION", TCL_EXCEPTION);
+       ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
+       ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
+       ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
+       ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
+       ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
+       ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
+       ins_string(d, "TK_VERSION", TK_VERSION);
+       ins_string(d, "TCL_VERSION", TCL_VERSION);
+
+       PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
+
+       Tktt_Type.ob_type = &PyType_Type;
+       PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
+
+
+#ifdef TK_AQUA
+       /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
+        * start waking up.  Note that Tcl_FindExecutable will do this, this
+        * code must be above it! The original warning from
+        * tkMacOSXAppInit.c is copied below.
+        *
+        * NB - You have to swap in the Tk Notifier BEFORE you start up the
+        * Tcl interpreter for now.  It probably should work to do this
+        * in the other order, but for now it doesn't seem to.
+        *
+        */
+       Tk_MacOSXSetupTkNotifier();
+#endif
+
+
+       /* This helps the dynamic loader; in Unicode aware Tcl versions
+          it also helps Tcl find its encodings. */
+       Tcl_FindExecutable(Py_GetProgramName());
+
+       if (PyErr_Occurred())
+               return;
+
+#if 0
+       /* This was not a good idea; through <Destroy> bindings,
+          Tcl_Finalize() may invoke Python code but at that point the
+          interpreter and thread state have already been destroyed! */
+       Py_AtExit(Tcl_Finalize);
+#endif
+
+#ifdef macintosh
+       /*
+       ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
+       ** Most of the initializations in that routine (toolbox init calls and
+       ** such) have already been done for us, so we only need these.
+       */
+       tcl_macQdPtr = &qd;
+
+       Tcl_MacSetEventProc(PyMacConvertEvent);
+#if GENERATINGCFM
+       mac_addlibresources();
+#endif /* GENERATINGCFM */
+#endif /* macintosh */
+}
+
+
+\f
+#ifdef macintosh
+
+/*
+** Anyone who embeds Tcl/Tk on the Mac must define panic().
+*/
+
+void
+panic(char * format, ...)
+{
+       va_list varg;
+       
+       va_start(varg, format);
+       
+       vfprintf(stderr, format, varg);
+       (void) fflush(stderr);
+       
+       va_end(varg);
+
+       Py_FatalError("Tcl/Tk panic");
+}
+
+/*
+** Pass events to SIOUX before passing them to Tk.
+*/
+
+static int
+PyMacConvertEvent(EventRecord *eventPtr)
+{
+       WindowPtr frontwin;
+       /*
+       ** Sioux eats too many events, so we don't pass it everything.  We
+       ** always pass update events to Sioux, and we only pass other events if
+       ** the Sioux window is frontmost. This means that Tk menus don't work
+       ** in that case, but at least we can scroll the sioux window.
+       ** Note that the SIOUXIsAppWindow() routine we use here is not really
+       ** part of the external interface of Sioux...
+       */
+       frontwin = FrontWindow();
+       if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
+               if (SIOUXHandleOneEvent(eventPtr))
+                       return 0; /* Nothing happened to the Tcl event queue */
+       }
+       return TkMacConvertEvent(eventPtr);
+}
+
+#if GENERATINGCFM
+
+/*
+** Additional Mac specific code for dealing with shared libraries.
+*/
+
+#include <Resources.h>
+#include <CodeFragments.h>
+
+static int loaded_from_shlib = 0;
+static FSSpec library_fss;
+
+/*
+** If this module is dynamically loaded the following routine should
+** be the init routine. It takes care of adding the shared library to
+** the resource-file chain, so that the tk routines can find their
+** resources.
+*/
+OSErr pascal
+init_tkinter_shlib(CFragInitBlockPtr data)
+{
+       __initialize();
+       if ( data == nil ) return noErr;
+       if ( data->fragLocator.where == kDataForkCFragLocator ) {
+               library_fss = *data->fragLocator.u.onDisk.fileSpec;
+               loaded_from_shlib = 1;
+       } else if ( data->fragLocator.where == kResourceCFragLocator ) {
+               library_fss = *data->fragLocator.u.inSegs.fileSpec;
+               loaded_from_shlib = 1;
+       }
+       return noErr;
+}
+
+/*
+** Insert the library resources into the search path. Put them after
+** the resources from the application. Again, we ignore errors.
+*/
+static
+mac_addlibresources(void)
+{
+       if ( !loaded_from_shlib ) 
+               return;
+       (void)FSpOpenResFile(&library_fss, fsRdPerm);
+}
+
+#endif /* GENERATINGCFM */
+#endif /* macintosh */
diff --git a/src/patchTkinter/setup.py.in b/src/patchTkinter/setup.py.in
new file mode 100644 (file)
index 0000000..3c77cb4
--- /dev/null
@@ -0,0 +1,223 @@
+# Autodetecting setup.py script for building the Python extensions
+#
+# To be fixed:
+#   Implement --disable-modules setting
+#
+
+__version__ = "$Revision: 1.1.1.1 $"
+
+import sys, os, getopt
+from distutils import sysconfig
+from distutils import text_file
+from distutils.errors import *
+from distutils.core import Extension, setup
+from distutils.command.build_ext import build_ext
+
+# This global variable is used to hold the list of modules to be disabled.
+disabled_module_list = []
+
+def find_file(filename, std_dirs, paths):
+    """Searches for the directory where a given file is located,
+    and returns a possibly-empty list of additional directories, or None
+    if the file couldn't be found at all.
+
+    'filename' is the name of a file, such as readline.h or libcrypto.a.
+    'std_dirs' is the list of standard system directories; if the
+        file is found in one of them, no additional directives are needed.
+    'paths' is a list of additional locations to check; if the file is
+        found in one of them, the resulting list will contain the directory.
+    """
+
+    # Check the standard locations
+    for dir in std_dirs:
+        f = os.path.join(dir, filename)
+        if os.path.exists(f): return []
+
+    # Check the additional directories
+    for dir in paths:
+        f = os.path.join(dir, filename)
+        if os.path.exists(f):
+            return [dir]
+
+    # Not found anywhere
+    return None
+
+def find_library_file(compiler, libname, std_dirs, paths):
+    filename = compiler.library_filename(libname, lib_type='shared')
+    result = find_file(filename, std_dirs, paths)
+    if result is not None: return result
+
+    filename = compiler.library_filename(libname, lib_type='static')
+    result = find_file(filename, std_dirs, paths)
+    return result
+
+def module_enabled(extlist, modname):
+    """Returns whether the module 'modname' is present in the list
+    of extensions 'extlist'."""
+    extlist = [ext for ext in extlist if ext.name == modname]
+    return len(extlist)
+
+class PyBuildExt(build_ext):
+
+    def build_extensions(self):
+
+        # Detect which modules should be compiled
+        self.detect_modules()
+
+        # Remove modules that are present on the disabled list
+        self.extensions = [ext for ext in self.extensions
+                           if ext.name not in disabled_module_list]
+
+        # When you run "make CC=altcc" or something similar, you really want
+        # those environment variables passed into the setup.py phase.  Here's
+        # a small set of useful ones.
+        compiler = os.environ.get('CC')
+        linker_so = os.environ.get('LDSHARED')
+        args = {}
+        # unfortunately, distutils doesn't let us provide separate C and C++
+        # compilers
+        if compiler is not None:
+            (ccshared,) = sysconfig.get_config_vars('CCSHARED')
+            args['compiler_so'] = compiler + ' ' + ccshared
+        if linker_so is not None:
+            args['linker_so'] = linker_so + ' -shared'
+        self.compiler.set_executables(**args)
+
+        build_ext.build_extensions(self)
+
+    def build_extension(self, ext):
+
+        try:
+            build_ext.build_extension(self, ext)
+        except (CCompilerError, DistutilsError), why:
+            self.announce('WARNING: building of extension "%s" failed: %s' %
+                          (ext.name, sys.exc_info()[1]))
+
+    def get_platform (self):
+        # Get value of sys.platform
+        platform = sys.platform
+        if platform[:6] =='cygwin':
+            platform = 'cygwin'
+        elif platform[:4] =='beos':
+            platform = 'beos'
+
+        return platform
+
+    def detect_modules(self):
+        # Ensure that /usr/local is always used
+        if '/usr/local/lib' not in self.compiler.library_dirs:
+            self.compiler.library_dirs.insert(0, '/usr/local/lib')
+        if '/usr/local/include' not in self.compiler.include_dirs:
+            self.compiler.include_dirs.insert(0, '/usr/local/include' )
+
+        # lib_dirs and inc_dirs are used to search for files;
+        # if a file is found in one of those directories, it can
+        # be assumed that no additional -I,-L directives are needed.
+        lib_dirs = self.compiler.library_dirs + ['/lib', '/usr/lib']
+        inc_dirs = self.compiler.include_dirs + ['/usr/include'] 
+        exts = []
+
+        platform = self.get_platform()
+        
+        # Check for MacOS X, which doesn't need libm.a at all
+        math_libs = ['m']
+        if platform in ['Darwin1.2', 'beos']:
+            math_libs = []
+
+        # Call the method for detecting whether _tkinter can be compiled
+        self.detect_tkinter(inc_dirs, lib_dirs)
+
+
+    def detect_tkinter(self, inc_dirs, lib_dirs):
+        # The _tkinter module.
+        
+        # Assume we haven't found any of the libraries or include files
+        tcllib = tklib = tcl_includes = tk_includes = None
+        for version in ['8.4', '8.3', '8.2', '8.1', '8.0']:
+             tklib = self.compiler.find_library_file(lib_dirs,
+                                                     'tk' + version )
+             tcllib = self.compiler.find_library_file(lib_dirs,
+                                                      'tcl' + version )
+             if tklib and tcllib:
+                # Exit the loop when we've found the Tcl/Tk libraries
+                break
+
+        # Now check for the header files
+        if tklib and tcllib:
+            # Check for the include files on Debian, where
+            # they're put in /usr/include/{tcl,tk}X.Y
+            debian_tcl_include = [ '/usr/include/tcl' + version ]
+            debian_tk_include =  [ '/usr/include/tk'  + version ] + debian_tcl_include
+            tcl_includes = find_file('tcl.h', inc_dirs, debian_tcl_include)
+            tk_includes = find_file('tk.h', inc_dirs, debian_tk_include)
+
+        if (tcllib is None or tklib is None and
+            tcl_includes is None or tk_includes is None):
+            # Something's missing, so give up
+            return
+
+        # OK... everything seems to be present for Tcl/Tk.
+
+        include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = []
+        for dir in tcl_includes + tk_includes:
+            if dir not in include_dirs:
+                include_dirs.append(dir)
+
+        # Check for various platform-specific directories
+        platform = self.get_platform()
+        if platform == 'sunos5':
+            include_dirs.append('/usr/openwin/include')
+            added_lib_dirs.append('/usr/openwin/lib')
+        elif os.path.exists('/usr/X11R6/include'):
+            include_dirs.append('/usr/X11R6/include')
+            added_lib_dirs.append('/usr/X11R6/lib')
+        elif os.path.exists('/usr/X11R5/include'):
+            include_dirs.append('/usr/X11R5/include')
+            added_lib_dirs.append('/usr/X11R5/lib')
+        else:
+            # Assume default location for X11
+            include_dirs.append('/usr/X11/include')
+            added_lib_dirs.append('/usr/X11/lib')
+
+        # Check for BLT extension
+        if self.compiler.find_library_file(lib_dirs + added_lib_dirs, 'BLT8.0'):
+            defs.append( ('WITH_BLT', 1) )
+            libs.append('BLT8.0')
+
+        # Add the Tcl/Tk libraries
+        libs.append('tk'+version)
+        libs.append('tcl'+version)
+
+        if platform in ['aix3', 'aix4']:
+            libs.append('ld')
+
+        # Finally, link with the X11 libraries
+        libs.append('X11')
+
+        ext = Extension('_tkinter', ['@srcdir@/_tkinter.c', '@srcdir@/tkappinit.c'],
+                        define_macros=[('WITH_APPINIT', 1)] + defs,
+                        include_dirs = include_dirs,
+                        libraries = libs,
+                        library_dirs = added_lib_dirs,
+                        )
+        self.extensions[0]=ext
+
+        # XXX handle these, but how to detect?
+        # *** Uncomment and edit for PIL (TkImaging) extension only:
+        #       -DWITH_PIL -I../Extensions/Imaging/libImaging  tkImaging.c \
+        # *** Uncomment and edit for TOGL extension only:
+        #       -DWITH_TOGL togl.c \
+        # *** Uncomment these for TOGL extension only:
+        #       -lGL -lGLU -lXext -lXmu \
+
+def main():
+    setup(name = 'Python standard library',
+          version = '%d.%d' % sys.version_info[:2],
+          ext_modules=[Extension('_tkinter', ['_tkinter.c'])],
+          cmdclass = {'build_ext':PyBuildExt},
+        )
+
+# --install-platlib
+if __name__ == '__main__':
+    #sysconfig.set_python_build()
+    main()
diff --git a/src/patchTkinter/tkappinit.c b/src/patchTkinter/tkappinit.c
new file mode 100644 (file)
index 0000000..96c545d
--- /dev/null
@@ -0,0 +1,139 @@
+/* appinit.c -- Tcl and Tk application initialization.
+
+   The function Tcl_AppInit() below initializes various Tcl packages.
+   It is called for each Tcl interpreter created by _tkinter.create().
+   It needs to be compiled with -DWITH_<package> flags for each package
+   that you are statically linking with.  You may have to add sections
+   for packages not yet listed below.
+
+   Note that those packages for which Tcl_StaticPackage() is called with
+   a NULL first argument are known as "static loadable" packages to
+   Tcl but not actually initialized.  To use these, you have to load
+   it explicitly, e.g. tkapp.eval("load {} Blt").
+ */
+
+#include <tcl.h>
+#include <tk.h>
+
+int
+Tcl_AppInit(Tcl_Interp *interp)
+{
+       Tk_Window main_window;
+
+#ifdef TK_AQUA
+#ifndef MAX_PATH_LEN
+#define MAX_PATH_LEN 1024
+#endif
+       char tclLibPath[MAX_PATH_LEN], tkLibPath[MAX_PATH_LEN];
+       Tcl_Obj*        pathPtr;
+
+        /* pre- Tcl_Init code copied from tkMacOSXAppInit.c */
+       Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tcllibrary",
+               tclLibPath, MAX_PATH_LEN, 0);
+
+       if (tclLibPath[0] != '\0') {
+               Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY);
+               Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY);
+               Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY);
+       }
+       
+       if (tclLibPath[0] != '\0') {
+               Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY);
+               Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY);
+               Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY);
+       }
+#endif
+       if (Tcl_Init (interp) == TCL_ERROR)
+               return TCL_ERROR;
+
+#ifdef TK_AQUA
+        /* pre- Tk_Init code copied from tkMacOSXAppInit.c */
+       Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tklibrary",
+            tkLibPath, MAX_PATH_LEN, 1);
+
+       if (tclLibPath[0] != '\0') {
+               pathPtr = Tcl_NewStringObj(tclLibPath, -1);
+       } else {
+               Tcl_Obj *pathPtr = TclGetLibraryPath();
+       }
+
+       if (tkLibPath[0] != '\0') {
+               Tcl_Obj *objPtr;
+
+               Tcl_SetVar(interp, "tk_library", tkLibPath, TCL_GLOBAL_ONLY);
+               objPtr = Tcl_NewStringObj(tkLibPath, -1);
+               Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
+       }
+
+       TclSetLibraryPath(pathPtr);
+#endif
+
+       if (Tk_Init (interp) == TCL_ERROR)
+               return TCL_ERROR;
+
+       main_window = Tk_MainWindow(interp);
+
+#ifdef TK_AQUA
+       TkMacOSXInitAppleEvents(interp);
+       TkMacOSXInitMenus(interp);
+#endif
+    
+#ifdef WITH_MOREBUTTONS
+       {
+               extern Tcl_CmdProc studButtonCmd;
+               extern Tcl_CmdProc triButtonCmd;
+
+               Tcl_CreateCommand(interp, "studbutton", studButtonCmd,
+                                 (ClientData) main_window, NULL);
+               Tcl_CreateCommand(interp, "tributton", triButtonCmd,
+                                 (ClientData) main_window, NULL);
+       }
+#endif
+
+#ifdef WITH_PIL /* 0.2b5 and later -- not yet released as of May 14 */
+       {
+               extern void TkImaging_Init(Tcl_Interp *);
+               TkImaging_Init(interp);
+               /* XXX TkImaging_Init() doesn't have the right return type */
+               /*Tcl_StaticPackage(interp, "Imaging", TkImaging_Init, NULL);*/
+       }
+#endif
+
+#ifdef WITH_PIL_OLD /* 0.2b4 and earlier */
+       {
+               extern void TkImaging_Init(void);
+               /* XXX TkImaging_Init() doesn't have the right prototype */
+               /*Tcl_StaticPackage(interp, "Imaging", TkImaging_Init, NULL);*/
+       }
+#endif
+
+#ifdef WITH_TIX
+        {
+                extern int Tix_Init(Tcl_Interp *interp);
+                extern int Tix_SafeInit(Tcl_Interp *interp);
+                Tcl_StaticPackage(NULL, "Tix", Tix_Init, Tix_SafeInit);
+        }
+#endif
+
+#ifdef WITH_BLT
+       {
+               extern int Blt_Init(Tcl_Interp *);
+               extern int Blt_SafeInit(Tcl_Interp *);
+               Tcl_StaticPackage(NULL, "Blt", Blt_Init, Blt_SafeInit);
+       }
+#endif
+
+#ifdef WITH_TOGL
+       {
+               /* XXX I've heard rumors that this doesn't work */
+               extern int Togl_Init(Tcl_Interp *);
+               /* XXX Is there no Togl_SafeInit? */
+               Tcl_StaticPackage(NULL, "Togl", Togl_Init, NULL);
+       }
+#endif
+
+#ifdef WITH_XXX
+
+#endif
+       return TCL_OK;
+}