From: salome <> Date: Wed, 3 Aug 2005 10:06:02 +0000 (+0000) Subject: Suppression des paquets TclQtNotifier (déporté dans PAL_SRC) et patchTkinter (obsolète) X-Git-Tag: V1_0_4^0 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=b1c790fd05fd7704bae5f9f93d1f6832a8b25af4;p=modules%2Feficas.git Suppression des paquets TclQtNotifier (déporté dans PAL_SRC) et patchTkinter (obsolète) --- diff --git a/src/Makefile.in b/src/Makefile.in index d83b3d9e..4cbcbf35 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -4,7 +4,7 @@ # Author : Paul RASCLE, EDF # Project : SALOME # Copyright : EDF 2001 -# $Header: /home/salome/PlateFormePAL/Bases_CVS_EDF/Modules_EDF/EFICAS_SRC/src/Makefile.in,v 1.1.1.1 2004/09/28 09:41:16 salome Exp $ +# $Header: /home/salome/PlateFormePAL/Bases_CVS_EDF/Modules_EDF/EFICAS_SRC/src/Makefile.in,v 1.2 2004/12/10 16:43:25 salome Exp $ #============================================================================== # source path @@ -15,6 +15,6 @@ VPATH=.:@srcdir@ @COMMENCE@ -SUBDIRS = TclQtNotifier EFICAS EFICASGUI +SUBDIRS = EFICAS EFICASGUI @MODULE@ diff --git a/src/TclQtNotifier/Makefile.in b/src/TclQtNotifier/Makefile.in deleted file mode 100644 index c85d71dc..00000000 --- a/src/TclQtNotifier/Makefile.in +++ /dev/null @@ -1,48 +0,0 @@ -# -* Makefile *- -# -# Author : Nicolas REJNERI -# Date : Sun May 05 11:45:40 2002 -# $Header $ -# - -# source path -top_srcdir=@top_srcdir@ -top_builddir=../.. -srcdir=@srcdir@ -VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome - - -@COMMENCE@ - -# header files -EXPORT_HEADERS= - -# Libraries targets -LIB = - -LIB_SRC = - -LIB_MOC = - -LIB_CLIENT_IDL = - -LIB_SERVER_IDL = - -EXPORT_PYSCRIPTS = - -# additionnal information to compil and link file - -lib: notifqt.so - -notifqt.so: moc_notify.cpp - python setup.py install --install-lib=$(top_builddir)/lib/salome - - -install: notifqt.so - $(INSTALL) -d $(libdir) - cp -p $(top_builddir)/lib/salome/notifqt.so $(libdir) - - -#pattern rules -moc_%.cpp : %.h - $(MOC) $< -o $@ diff --git a/src/TclQtNotifier/moc_notify.refcpp b/src/TclQtNotifier/moc_notify.refcpp deleted file mode 100644 index 4f13f468..00000000 --- a/src/TclQtNotifier/moc_notify.refcpp +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** -** 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 -#include - -#include -#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 19) -#error "This file was generated using the moc from 3.0.6. It" -#error "cannot be used with the include files from this version of Qt." -#error "(The moc has changed too much.)" -#endif - -const char *Notifier::className() const -{ - return "Notifier"; -} - -QMetaObject *Notifier::metaObj = 0; -static QMetaObjectCleanUp cleanUp_Notifier; - -#ifndef QT_NO_TRANSLATION -QString Notifier::tr( const char *s, const char *c ) -{ - if ( qApp ) - return qApp->translate( "Notifier", s, c, QApplication::DefaultCodec ); - else - return QString::fromLatin1( s ); -} -#ifndef QT_NO_TRANSLATION_UTF8 -QString Notifier::trUtf8( const char *s, const char *c ) -{ - if ( qApp ) - return qApp->translate( "Notifier", s, c, QApplication::UnicodeUTF8 ); - else - return QString::fromUtf8( s ); -} -#endif // QT_NO_TRANSLATION_UTF8 - -#endif // QT_NO_TRANSLATION - -QMetaObject* Notifier::staticMetaObject() -{ - if ( metaObj ) - return metaObj; - QMetaObject* parentObject = QObject::staticMetaObject(); - static const QUMethod slot_0 = {"dataReceived", 0, 0 }; - static const QUMethod slot_1 = {"dataWritable", 0, 0 }; - static const QUMethod slot_2 = {"dataExcept", 0, 0 }; - static const QMetaData slot_tbl[] = { - { "dataReceived()", &slot_0, QMetaData::Public }, - { "dataWritable()", &slot_1, QMetaData::Public }, - { "dataExcept()", &slot_2, QMetaData::Public } - }; - metaObj = QMetaObject::new_metaobject( - "Notifier", parentObject, - slot_tbl, 3, - 0, 0, -#ifndef QT_NO_PROPERTIES - 0, 0, - 0, 0, -#endif // QT_NO_PROPERTIES - 0, 0 ); - cleanUp_Notifier.setMetaObject( metaObj ); - return metaObj; -} - -void* Notifier::qt_cast( const char* clname ) -{ - if ( !qstrcmp( clname, "Notifier" ) ) return (Notifier*)this; - return QObject::qt_cast( clname ); -} - -bool Notifier::qt_invoke( int _id, QUObject* _o ) -{ - switch ( _id - staticMetaObject()->slotOffset() ) { - case 0: dataReceived(); break; - case 1: dataWritable(); break; - case 2: dataExcept(); break; - default: - return QObject::qt_invoke( _id, _o ); - } - return TRUE; -} - -bool Notifier::qt_emit( int _id, QUObject* _o ) -{ - return QObject::qt_emit(_id,_o); -} -#ifndef QT_NO_PROPERTIES - -bool Notifier::qt_property( int _id, int _f, QVariant* _v) -{ - return QObject::qt_property( _id, _f, _v); -} -#endif // QT_NO_PROPERTIES - - -const char *Timer::className() const -{ - return "Timer"; -} - -QMetaObject *Timer::metaObj = 0; -static QMetaObjectCleanUp cleanUp_Timer; - -#ifndef QT_NO_TRANSLATION -QString Timer::tr( const char *s, const char *c ) -{ - if ( qApp ) - return qApp->translate( "Timer", s, c, QApplication::DefaultCodec ); - else - return QString::fromLatin1( s ); -} -#ifndef QT_NO_TRANSLATION_UTF8 -QString Timer::trUtf8( const char *s, const char *c ) -{ - if ( qApp ) - return qApp->translate( "Timer", s, c, QApplication::UnicodeUTF8 ); - else - return QString::fromUtf8( s ); -} -#endif // QT_NO_TRANSLATION_UTF8 - -#endif // QT_NO_TRANSLATION - -QMetaObject* Timer::staticMetaObject() -{ - if ( metaObj ) - return metaObj; - QMetaObject* parentObject = QObject::staticMetaObject(); - static const QUMethod slot_0 = {"timeout", 0, 0 }; - static const QMetaData slot_tbl[] = { - { "timeout()", &slot_0, QMetaData::Public } - }; - metaObj = QMetaObject::new_metaobject( - "Timer", parentObject, - slot_tbl, 1, - 0, 0, -#ifndef QT_NO_PROPERTIES - 0, 0, - 0, 0, -#endif // QT_NO_PROPERTIES - 0, 0 ); - cleanUp_Timer.setMetaObject( metaObj ); - return metaObj; -} - -void* Timer::qt_cast( const char* clname ) -{ - if ( !qstrcmp( clname, "Timer" ) ) return (Timer*)this; - return QObject::qt_cast( clname ); -} - -bool Timer::qt_invoke( int _id, QUObject* _o ) -{ - switch ( _id - staticMetaObject()->slotOffset() ) { - case 0: timeout(); break; - default: - return QObject::qt_invoke( _id, _o ); - } - return TRUE; -} - -bool Timer::qt_emit( int _id, QUObject* _o ) -{ - return QObject::qt_emit(_id,_o); -} -#ifndef QT_NO_PROPERTIES - -bool Timer::qt_property( int _id, int _f, QVariant* _v) -{ - return QObject::qt_property( _id, _f, _v); -} -#endif // QT_NO_PROPERTIES diff --git a/src/TclQtNotifier/notifqtmodule.cpp b/src/TclQtNotifier/notifqtmodule.cpp deleted file mode 100644 index 46c3e3ab..00000000 --- a/src/TclQtNotifier/notifqtmodule.cpp +++ /dev/null @@ -1,877 +0,0 @@ -#include -#include -#include -using namespace std; -#include -#include -#include -#include -#include - -/* - * 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 - */ -#if (QT_VERSION >= 0x030200) -#define QT32 -#else -#define QT30 -#endif - -#ifdef QT30 -#define private public /* We need to use processNextEvent(), - therefore we need - access to the internal variables. */ -#include -#undef private /* On revient au normal */ -#else -#include -#include -#endif - -#include - - -#include "notify.h" -#include - -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<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(); - break; - } - 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); -} diff --git a/src/TclQtNotifier/notify.h b/src/TclQtNotifier/notify.h deleted file mode 100644 index 00f908bb..00000000 --- a/src/TclQtNotifier/notify.h +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include -#include - -#include -EXTERN int TclInExit _ANSI_ARGS_((void)); - -class Notifier; - -typedef struct FileHandler { - int fd; - int mask; /* Mask of desired events: TCL_READABLE, etc. */ - int readyMask; /* Events that have been seen since the - last time FileHandlerEventProc was called - for this file. */ - Notifier *qtNotifier; - Tcl_FileProc *proc; /* Procedure to call, in the style of - * Tcl_CreateFileHandler. */ - ClientData clientData; /* Argument to pass to proc. */ - struct FileHandler *nextPtr;/* Next in list of all files we care about. */ -} FileHandler; - -class Notifier : public QObject -{ - Q_OBJECT -public: - Notifier(FileHandler *,int); -public slots: - void dataReceived(); - void dataWritable(); - void dataExcept(); -private: - QSocketNotifier *sn; - FileHandler *fhdr; -}; - -class Filter : public QObject -{ -public: - Filter(); - bool eventFilter( QObject *, QEvent * ); - int mustFilter; -}; - -class Timer : public QObject -{ - Q_OBJECT -public: - Timer(); - QTimer *timer; -public slots: - void timeout(); -}; - diff --git a/src/TclQtNotifier/setup.py.in b/src/TclQtNotifier/setup.py.in deleted file mode 100644 index 92cdf57e..00000000 --- a/src/TclQtNotifier/setup.py.in +++ /dev/null @@ -1,134 +0,0 @@ -from distutils.core import setup, Extension - -import os,sys - -TCLHOME=os.getenv("TCLHOME") -if not TCLHOME: - print "TCLHOME not set : use /usr" - TCLHOME="/usr" -TCLINCL=os.path.join(TCLHOME,"include") -TCLLIB=os.path.join(TCLHOME,"lib") - -# _CS_gbo_ Ajout de TKHOME pour la modularité des installations. Si -# TKHOME n'est pas définie, elle prend la valeur de TCLHOME. -TKHOME=os.getenv("TKHOME") -if not TKHOME: - print "TKHOME not set : use ", TCLHOME - TKHOME=TCLHOME -TKINCL=os.path.join(TKHOME,"include") -TKLIB=os.path.join(TKHOME,"lib") - -# _CS_gbo_ Ajout de TIXHOME pour la modularité des installations. Si -# TIXHOME n'est pas définie, elle prend la valeur de TCLHOME. -TIXHOME=os.getenv("TIXHOME") -if not TIXHOME: - print "TIXHOME not set : use ", TCLHOME - TIXHOME=TCLHOME -TIXINCL=os.path.join(TIXHOME,"include") -TIXLIB=os.path.join(TIXHOME,"lib") - - -QT_INCLUDES="@QT_INCLUDES@".split() -SIP_INCLUDES="@SIP_INCLUDES@".split() -QT_LIBS="@QT_MT_LIBS@".split() -SIP_LIBS="@SIP_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 [] - # _CS_gbo_ A priori, c'est plutôt ce comportement qu'il faut implémenter - if os.path.exists(f): return [dir] - - # 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=[TCLINCL,TKINCL,TIXINCL] -lib_dirs=[TCLLIB,TKLIB,TIXLIB] - -# _CS_gbo_ Je pense qu'il faut dissocier la recherche dans les -# répertoires définis sur la base de TCLHOME (paramétrage utilisateur) -# de la recherche aux emplacement système par défaut. Par ailleurs, le -# positionnement du numéro de version sert ici à définir le nom de la -# bibliothèques à lié (libtcl8.3.so par exemple). Il serait plus -# pertinant de faire le même contrôle que pour les includes - -tcl_includes = find_file('tcl.h', inc_dirs, []) -tk_includes = find_file('tk.h', inc_dirs, []) -if tcl_includes and tk_includes: - # On recherche la bibliothèque "versionnées" - for version in ['8.4', '8.3', '8.2', '8.1', '8.0']: - libtcl = 'libtcl' + version + '.so' - libtk = 'libtk' + version + '.so' - tcl_lib = find_file(libtcl, lib_dirs, []) - tk_lib = find_file(libtk, lib_dirs, []) - if tcl_lib and tk_lib: - # On retiend ce numéro de version - break - - -# -# Recherche des includes dans les emplacement système par -# défaut. Cette boucle est entammée uniquement si les include n'ont pas -# encore été déterminés. -# -if not tcl_includes or not tk_includes or not tcl_lib or not tk_lib: - 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', [], debian_tcl_include) - tk_includes = find_file('tk.h', [], debian_tk_include) - if tcl_includes and tk_includes: - break - # _CS_gbo_ Si quand bien même on ne trouve pas les éléments - # recherchés, je pense qu'il faut arrêter le setup, il y a un problème - # de configuration. - if not tcl_includes or not tk_includes: - print "setup.py: Impossible de définir la configuration Tcl/Tk" - sys.exit(1) - - -print "Found Tk version:",version -print "Found Tcl includes:",tcl_includes -print "Found Tk includes:",tk_includes - -include_dirs=[".", "@srcdir@"]+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=lib_dirs, - libraries=libs_tk, - extra_compile_args= SIP_INCLUDES + QT_INCLUDES, - extra_objects=[], - extra_link_args=QT_LIBS + PYQT_LIBS + SIP_LIBS, - ) - ]) - diff --git a/src/patchTkinter/Makefile.in b/src/patchTkinter/Makefile.in deleted file mode 100644 index dcea295c..00000000 --- a/src/patchTkinter/Makefile.in +++ /dev/null @@ -1,43 +0,0 @@ -# -* Makefile *- -# -# Author : Nicolas REJNERI -# Date : Sun May 05 11:45:40 2002 -# $Header $ -# - -# source path -top_srcdir=@top_srcdir@ -top_builddir=../.. -srcdir=@srcdir@ -VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome - - -@COMMENCE@ - -# header files -EXPORT_HEADERS= - -# Libraries targets -LIB = - -LIB_SRC = - -LIB_MOC = - -LIB_CLIENT_IDL = - -LIB_SERVER_IDL = - -EXPORT_PYSCRIPTS = - -# additionnal information to compil and link file - -_tkinter.so: - python setup.py install --install-lib=$(top_builddir)/lib/salome - -lib: _tkinter.so - -install: _tkinter.so - $(INSTALL) -d $(libdir) - cp -p $(top_builddir)/lib/salome/_tkinter.so $(libdir) - diff --git a/src/patchTkinter/_tkinter.c b/src/patchTkinter/_tkinter.c deleted file mode 100644 index 35e9bbb3..00000000 --- a/src/patchTkinter/_tkinter.c +++ /dev/null @@ -1,2318 +0,0 @@ -/*********************************************************** -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 - -#ifdef WITH_THREAD -#include "pythread.h" -#endif - -#ifdef MS_WINDOWS -#include -#endif - -#ifdef macintosh -#define MAC_TCL -#endif - -#ifdef TK_FRAMEWORK -#include -#include -#else -#include -#include -#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 -/* And this one we need to clear the menu bar */ -#include -#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 -#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 /* For EventRecord */ - -typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr); -void Tcl_MacSetEventProc(TclMacConvertEventPtr procPtr); -int TkMacConvertEvent(EventRecord *eventPtr); - -staticforward int PyMacConvertEvent(EventRecord *eventPtr); - -#include -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)) - - - -/**** Error Handling ****/ - -static PyObject *Tkinter_TclError; -static int quitMainLoop = 0; -static int errorInCmd = 0; -static PyObject *excInCmd; -static PyObject *valInCmd; -static PyObject *trbInCmd; - - - -static PyObject * -Tkinter_Error(PyObject *v) -{ - PyErr_SetString(Tkinter_TclError, Tkapp_Result(v)); - return NULL; -} - - - -/**** 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 */ - - -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); - } -} - - - -#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; -} - - - -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; -} - - - -/**** 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 */ - - - - -/* 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; -} - - - -/** 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 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; -} - - - -/** 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); -} - - - -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); -} - - - -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); -} - - - -/** 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; -} - - - -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; -} - - - -/** 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 -} - - - -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; -} - - - -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; -} - - - -#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 */ - - -/**** 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), "", 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 */ -}; - - - -/** 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; -} - - -/** 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)); -} - - - -/**** 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} -}; - - - -/**** 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 */ -}; - - - -/**** 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 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 */ -} - - - -#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 -#include - -static int loaded_from_shlib = 0; -static FSSpec library_fss; - -/* -** If this module is dynamically loaded the following routine should -** be the init routine. It takes care of adding the shared library to -** the resource-file chain, so that the tk routines can find their -** resources. -*/ -OSErr pascal -init_tkinter_shlib(CFragInitBlockPtr data) -{ - __initialize(); - if ( data == nil ) return noErr; - if ( data->fragLocator.where == kDataForkCFragLocator ) { - library_fss = *data->fragLocator.u.onDisk.fileSpec; - loaded_from_shlib = 1; - } else if ( data->fragLocator.where == kResourceCFragLocator ) { - library_fss = *data->fragLocator.u.inSegs.fileSpec; - loaded_from_shlib = 1; - } - return noErr; -} - -/* -** Insert the library resources into the search path. Put them after -** the resources from the application. Again, we ignore errors. -*/ -static -mac_addlibresources(void) -{ - if ( !loaded_from_shlib ) - return; - (void)FSpOpenResFile(&library_fss, fsRdPerm); -} - -#endif /* GENERATINGCFM */ -#endif /* macintosh */ diff --git a/src/patchTkinter/setup.py.in b/src/patchTkinter/setup.py.in deleted file mode 100644 index 3c77cb45..00000000 --- a/src/patchTkinter/setup.py.in +++ /dev/null @@ -1,223 +0,0 @@ -# Autodetecting setup.py script for building the Python extensions -# -# To be fixed: -# Implement --disable-modules setting -# - -__version__ = "$Revision: 1.1.1.1 $" - -import sys, os, getopt -from distutils import sysconfig -from distutils import text_file -from distutils.errors import * -from distutils.core import Extension, setup -from distutils.command.build_ext import build_ext - -# This global variable is used to hold the list of modules to be disabled. -disabled_module_list = [] - -def find_file(filename, std_dirs, paths): - """Searches for the directory where a given file is located, - and returns a possibly-empty list of additional directories, or None - if the file couldn't be found at all. - - 'filename' is the name of a file, such as readline.h or libcrypto.a. - 'std_dirs' is the list of standard system directories; if the - file is found in one of them, no additional directives are needed. - 'paths' is a list of additional locations to check; if the file is - found in one of them, the resulting list will contain the directory. - """ - - # Check the standard locations - for dir in std_dirs: - f = os.path.join(dir, filename) - if os.path.exists(f): return [] - - # Check the additional directories - for dir in paths: - f = os.path.join(dir, filename) - if os.path.exists(f): - return [dir] - - # Not found anywhere - return None - -def find_library_file(compiler, libname, std_dirs, paths): - filename = compiler.library_filename(libname, lib_type='shared') - result = find_file(filename, std_dirs, paths) - if result is not None: return result - - filename = compiler.library_filename(libname, lib_type='static') - result = find_file(filename, std_dirs, paths) - return result - -def module_enabled(extlist, modname): - """Returns whether the module 'modname' is present in the list - of extensions 'extlist'.""" - extlist = [ext for ext in extlist if ext.name == modname] - return len(extlist) - -class PyBuildExt(build_ext): - - def build_extensions(self): - - # Detect which modules should be compiled - self.detect_modules() - - # Remove modules that are present on the disabled list - self.extensions = [ext for ext in self.extensions - if ext.name not in disabled_module_list] - - # When you run "make CC=altcc" or something similar, you really want - # those environment variables passed into the setup.py phase. Here's - # a small set of useful ones. - compiler = os.environ.get('CC') - linker_so = os.environ.get('LDSHARED') - args = {} - # unfortunately, distutils doesn't let us provide separate C and C++ - # compilers - if compiler is not None: - (ccshared,) = sysconfig.get_config_vars('CCSHARED') - args['compiler_so'] = compiler + ' ' + ccshared - if linker_so is not None: - args['linker_so'] = linker_so + ' -shared' - self.compiler.set_executables(**args) - - build_ext.build_extensions(self) - - def build_extension(self, ext): - - try: - build_ext.build_extension(self, ext) - except (CCompilerError, DistutilsError), why: - self.announce('WARNING: building of extension "%s" failed: %s' % - (ext.name, sys.exc_info()[1])) - - def get_platform (self): - # Get value of sys.platform - platform = sys.platform - if platform[:6] =='cygwin': - platform = 'cygwin' - elif platform[:4] =='beos': - platform = 'beos' - - return platform - - def detect_modules(self): - # Ensure that /usr/local is always used - if '/usr/local/lib' not in self.compiler.library_dirs: - self.compiler.library_dirs.insert(0, '/usr/local/lib') - if '/usr/local/include' not in self.compiler.include_dirs: - self.compiler.include_dirs.insert(0, '/usr/local/include' ) - - # lib_dirs and inc_dirs are used to search for files; - # if a file is found in one of those directories, it can - # be assumed that no additional -I,-L directives are needed. - lib_dirs = self.compiler.library_dirs + ['/lib', '/usr/lib'] - inc_dirs = self.compiler.include_dirs + ['/usr/include'] - exts = [] - - platform = self.get_platform() - - # Check for MacOS X, which doesn't need libm.a at all - math_libs = ['m'] - if platform in ['Darwin1.2', 'beos']: - math_libs = [] - - # Call the method for detecting whether _tkinter can be compiled - self.detect_tkinter(inc_dirs, lib_dirs) - - - def detect_tkinter(self, inc_dirs, lib_dirs): - # The _tkinter module. - - # Assume we haven't found any of the libraries or include files - tcllib = tklib = tcl_includes = tk_includes = None - for version in ['8.4', '8.3', '8.2', '8.1', '8.0']: - tklib = self.compiler.find_library_file(lib_dirs, - 'tk' + version ) - tcllib = self.compiler.find_library_file(lib_dirs, - 'tcl' + version ) - if tklib and tcllib: - # Exit the loop when we've found the Tcl/Tk libraries - break - - # Now check for the header files - if tklib and tcllib: - # Check for the include files on Debian, where - # they're put in /usr/include/{tcl,tk}X.Y - debian_tcl_include = [ '/usr/include/tcl' + version ] - debian_tk_include = [ '/usr/include/tk' + version ] + debian_tcl_include - tcl_includes = find_file('tcl.h', inc_dirs, debian_tcl_include) - tk_includes = find_file('tk.h', inc_dirs, debian_tk_include) - - if (tcllib is None or tklib is None and - tcl_includes is None or tk_includes is None): - # Something's missing, so give up - return - - # OK... everything seems to be present for Tcl/Tk. - - include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = [] - for dir in tcl_includes + tk_includes: - if dir not in include_dirs: - include_dirs.append(dir) - - # Check for various platform-specific directories - platform = self.get_platform() - if platform == 'sunos5': - include_dirs.append('/usr/openwin/include') - added_lib_dirs.append('/usr/openwin/lib') - elif os.path.exists('/usr/X11R6/include'): - include_dirs.append('/usr/X11R6/include') - added_lib_dirs.append('/usr/X11R6/lib') - elif os.path.exists('/usr/X11R5/include'): - include_dirs.append('/usr/X11R5/include') - added_lib_dirs.append('/usr/X11R5/lib') - else: - # Assume default location for X11 - include_dirs.append('/usr/X11/include') - added_lib_dirs.append('/usr/X11/lib') - - # Check for BLT extension - if self.compiler.find_library_file(lib_dirs + added_lib_dirs, 'BLT8.0'): - defs.append( ('WITH_BLT', 1) ) - libs.append('BLT8.0') - - # Add the Tcl/Tk libraries - libs.append('tk'+version) - libs.append('tcl'+version) - - if platform in ['aix3', 'aix4']: - libs.append('ld') - - # Finally, link with the X11 libraries - libs.append('X11') - - ext = Extension('_tkinter', ['@srcdir@/_tkinter.c', '@srcdir@/tkappinit.c'], - define_macros=[('WITH_APPINIT', 1)] + defs, - include_dirs = include_dirs, - libraries = libs, - library_dirs = added_lib_dirs, - ) - self.extensions[0]=ext - - # XXX handle these, but how to detect? - # *** Uncomment and edit for PIL (TkImaging) extension only: - # -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \ - # *** Uncomment and edit for TOGL extension only: - # -DWITH_TOGL togl.c \ - # *** Uncomment these for TOGL extension only: - # -lGL -lGLU -lXext -lXmu \ - -def main(): - setup(name = 'Python standard library', - version = '%d.%d' % sys.version_info[:2], - ext_modules=[Extension('_tkinter', ['_tkinter.c'])], - cmdclass = {'build_ext':PyBuildExt}, - ) - -# --install-platlib -if __name__ == '__main__': - #sysconfig.set_python_build() - main() diff --git a/src/patchTkinter/tkappinit.c b/src/patchTkinter/tkappinit.c deleted file mode 100644 index 96c545d7..00000000 --- a/src/patchTkinter/tkappinit.c +++ /dev/null @@ -1,139 +0,0 @@ -/* 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_ 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 -#include - -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; -}