@@ -83,6 +83,24 @@ PERFORMANCE OF THIS SOFTWARE.
8383#define HAVE_CREATEFILEHANDLER
8484#endif
8585
86+ #ifdef MS_WINDOWS
87+ #define FHANDLETYPE TCL_WIN_SOCKET
88+ #else
89+ #define FHANDLETYPE TCL_UNIX_FD
90+ #endif
91+
92+ #if TKMAJORMINOR < 8000
93+ #define FHANDLE Tcl_File
94+ #define MAKEFHANDLE (fd ) Tcl_GetFile((ClientData)(fd), FHANDLETYPE)
95+ #else
96+ #define FHANDLE int
97+ #define MAKEFHANDLE (fd ) (fd)
98+ #endif
99+
100+ #if defined(HAVE_CREATEFILEHANDLER ) && !defined(MS_WINDOWS )
101+ #define WAIT_FOR_STDIN
102+ #endif
103+
86104extern int Tk_GetNumMainWindows ();
87105
88106#ifdef macintosh
@@ -342,6 +360,10 @@ Tcl_AppInit(interp)
342360/* Initialize the Tk application; see the `main' function in
343361 * `tkMain.c'.
344362 */
363+
364+ static void EnableEventHook (); /* Forward */
365+ static void DisableEventHook (); /* Forward */
366+
345367static TkappObject *
346368Tkapp_New (screenName , baseName , className , interactive )
347369 char * screenName ;
@@ -392,6 +414,8 @@ Tkapp_New(screenName, baseName, className, interactive)
392414 if (Tcl_AppInit (v -> interp ) != TCL_OK )
393415 return (TkappObject * )Tkinter_Error (v );
394416
417+ EnableEventHook ();
418+
395419 return v ;
396420}
397421
@@ -1128,9 +1152,7 @@ Tkapp_CreateFileHandler(self, args)
11281152 PyObject * file , * func , * data ;
11291153 PyObject * idkey ;
11301154 int mask , id ;
1131- #if TKMAJORMINOR < 8000
1132- Tcl_File tfile ;
1133- #endif
1155+ FHANDLE tfile ;
11341156
11351157 if (!Tkapp_ClientDataDict ) {
11361158 if (!(Tkapp_ClientDataDict = PyDict_New ()))
@@ -1159,18 +1181,9 @@ Tkapp_CreateFileHandler(self, args)
11591181 }
11601182 Py_DECREF (idkey );
11611183
1162- #if TKMAJORMINOR < 8000
1163- #ifdef MS_WINDOWS
1164- /* We assume this is a socket... */
1165- tfile = Tcl_GetFile ((ClientData )id , TCL_WIN_SOCKET );
1166- #else /* !MS_WINDOWS */
1167- tfile = Tcl_GetFile ((ClientData )id , TCL_UNIX_FD );
1168- #endif /* !MS_WINDOWS */
1184+ tfile = MAKEFHANDLE (id );
11691185 /* Ought to check for null Tcl_File object... */
11701186 Tcl_CreateFileHandler (tfile , mask , FileHandler , (ClientData ) data );
1171- #else /* >= 8000 */
1172- Tcl_CreateFileHandler (id , mask , FileHandler , (ClientData ) data );
1173- #endif /* >= 8000 */
11741187 /* XXX fileHandlerDict */
11751188 Py_INCREF (Py_None );
11761189 return Py_None ;
@@ -1186,9 +1199,7 @@ Tkapp_DeleteFileHandler(self, args)
11861199 PyObject * idkey ;
11871200 PyObject * data ;
11881201 int id ;
1189- #if TKMAJORMINOR < 8000
1190- Tcl_File tfile ;
1191- #endif
1202+ FHANDLE tfile ;
11921203
11931204 if (!PyArg_ParseTuple (args , "O" , & file ))
11941205 return NULL ;
@@ -1207,18 +1218,9 @@ Tkapp_DeleteFileHandler(self, args)
12071218 PyDict_DelItem (Tkapp_ClientDataDict , idkey );
12081219 Py_DECREF (idkey );
12091220
1210- #if TKMAJORMINOR < 8000
1211- #ifdef MS_WINDOWS
1212- /* We assume this is a socket... */
1213- tfile = Tcl_GetFile ((ClientData )id , TCL_WIN_SOCKET );
1214- #else
1215- tfile = Tcl_GetFile ((ClientData )id , TCL_UNIX_FD );
1216- #endif
1221+ tfile = MAKEFHANDLE (id );
12171222 /* Ought to check for null Tcl_File object... */
12181223 Tcl_DeleteFileHandler (tfile );
1219- #else /* >= 8000 */
1220- Tcl_DeleteFileHandler (id );
1221- #endif /* >= 8000 */
12221224 /* XXX fileHandlerDict */
12231225 Py_INCREF (Py_None );
12241226 return Py_None ;
@@ -1511,6 +1513,7 @@ Tkapp_Dealloc(self)
15111513{
15121514 Tcl_DeleteInterp (Tkapp_Interp (self ));
15131515 PyMem_DEL (self );
1516+ DisableEventHook ();
15141517}
15151518
15161519static PyObject *
@@ -1584,22 +1587,41 @@ static PyMethodDef moduleMethods[] =
15841587 {NULL , NULL }
15851588};
15861589
1590+ #ifdef WAIT_FOR_STDIN
1591+ #define WAITFLAG 0
1592+
1593+ static int stdin_ready = 0 ;
1594+
1595+ static void
1596+ MyFileProc (clientData , mask )
1597+ void * clientData ;
1598+ int mask ;
1599+ {
1600+ stdin_ready = 1 ;
1601+ }
1602+ #else
1603+ #define WAITFLAG TCL_DONT_WAIT
1604+ #endif
1605+
15871606static PyInterpreterState * event_interp = NULL ;
15881607
15891608static int
15901609EventHook ()
15911610{
15921611 PyThreadState * tstate , * save_tstate ;
1612+ #ifdef WAIT_FOR_STDIN
1613+ FHANDLE tfile = MAKEFHANDLE (((int )fileno (stdin )));
15931614
1594- if (Tk_GetNumMainWindows () == 0 )
1595- return 0 ;
1596- if (event_interp == NULL )
1597- return 0 ;
1615+ stdin_ready = 0 ;
1616+ Tcl_CreateFileHandler (tfile , TCL_READABLE , MyFileProc , NULL );
1617+ #endif
15981618 tstate = PyThreadState_New (event_interp );
15991619 save_tstate = PyThreadState_Swap (NULL );
16001620 PyEval_RestoreThread (tstate );
1601- if (!errorInCmd )
1602- Tcl_DoOneEvent (TCL_DONT_WAIT );
1621+ #ifdef WAIT_FOR_STDIN
1622+ while (!errorInCmd && !stdin_ready )
1623+ #endif
1624+ Tcl_DoOneEvent (WAITFLAG );
16031625 if (errorInCmd ) {
16041626 errorInCmd = 0 ;
16051627 PyErr_Restore (excInCmd , valInCmd , trbInCmd );
@@ -1610,9 +1632,29 @@ EventHook()
16101632 PyEval_SaveThread ();
16111633 PyThreadState_Swap (save_tstate );
16121634 PyThreadState_Delete (tstate );
1635+ #ifdef WAIT_FOR_STDIN
1636+ Tcl_DeleteFileHandler (tfile );
1637+ #endif
16131638 return 0 ;
16141639}
16151640
1641+ static void
1642+ EnableEventHook ()
1643+ {
1644+ if (PyOS_InputHook == NULL ) {
1645+ event_interp = PyThreadState_Get ()-> interp ;
1646+ PyOS_InputHook = EventHook ;
1647+ }
1648+ }
1649+
1650+ static void
1651+ DisableEventHook ()
1652+ {
1653+ if (Tk_GetNumMainWindows () == 0 && PyOS_InputHook == EventHook ) {
1654+ PyOS_InputHook = NULL ;
1655+ }
1656+ }
1657+
16161658
16171659/* all errors will be checked in one fell swoop in init_tkinter() */
16181660static void
@@ -1670,11 +1712,6 @@ init_tkinter()
16701712 PyDict_SetItemString (d , "TkappType" , (PyObject * )& Tkapp_Type );
16711713 PyDict_SetItemString (d , "TkttType" , (PyObject * )& Tktt_Type );
16721714
1673- if (PyOS_InputHook == NULL ) {
1674- event_interp = PyThreadState_Get ()-> interp ;
1675- PyOS_InputHook = EventHook ;
1676- }
1677-
16781715 if (PyErr_Occurred ())
16791716 return ;
16801717
0 commit comments