--- /dev/null
+# -* 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
+
--- /dev/null
+this file is needed by cvs to create the directory
\ No newline at end of file
--- /dev/null
+# 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
--- /dev/null
+#=======================================================================
+# 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
+#=======================================================================
--- /dev/null
+THIS IS SALOME 2 RNTL - TESTPQT VERSION: 1.1a
--- /dev/null
+#!/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
--- /dev/null
+
+# -* 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
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+# 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"),
+)
--- /dev/null
+"""
+ 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,
+ }
+
--- /dev/null
+# 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"
+
--- /dev/null
+# 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"
+
--- /dev/null
+#==============================================================================
+# 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@
--- /dev/null
+#=============================================================================
+# 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
+
+ #--------------------------------------------------------------------------
+
--- /dev/null
+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()
--- /dev/null
+#=============================================================================
+# 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)
+
--- /dev/null
+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")
+
--- /dev/null
+# 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
--- /dev/null
+#==============================================================================
+# 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@
--- /dev/null
+# -* 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 $@
--- /dev/null
+/****************************************************************************
+** 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
--- /dev/null
+#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(¬ifierprocs);
+ * 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(¬ifierprocs);
+ * 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(¬ifier, 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(¬ifierprocs, 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(¬ifierprocs);
+ 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);
+}
--- /dev/null
+#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();
+};
+
--- /dev/null
+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 ,
+ )
+ ])
+
--- /dev/null
+# -* 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)
+
--- /dev/null
+/***********************************************************
+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 */
--- /dev/null
+# 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()
--- /dev/null
+/* 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;
+}