symbian-qemu-0.9.1-12/python-2.6.1/Modules/_tkinter.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /***********************************************************
       
     2 Copyright (C) 1994 Steen Lumholt.
       
     3 
       
     4                         All Rights Reserved
       
     5 
       
     6 ******************************************************************/
       
     7 
       
     8 /* _tkinter.c -- Interface to libtk.a and libtcl.a. */
       
     9 
       
    10 /* TCL/TK VERSION INFO:
       
    11 
       
    12 	Only Tcl/Tk 8.2 and later are supported.  Older versions are not
       
    13 	supported.  (Use Python 2.2 if you cannot upgrade your Tcl/Tk
       
    14 	libraries.)
       
    15 */
       
    16 
       
    17 /* XXX Further speed-up ideas, involving Tcl 8.0 features:
       
    18 
       
    19    - Register a new Tcl type, "Python callable", which can be called more
       
    20    efficiently and passed to Tcl_EvalObj() directly (if this is possible).
       
    21 
       
    22 */
       
    23 
       
    24 
       
    25 #include "Python.h"
       
    26 #include <ctype.h>
       
    27 
       
    28 #ifdef WITH_THREAD
       
    29 #include "pythread.h"
       
    30 #endif
       
    31 
       
    32 #ifdef MS_WINDOWS
       
    33 #include <windows.h>
       
    34 #endif
       
    35 
       
    36 /* Allow using this code in Python 2.[12] */
       
    37 #ifndef PyDoc_STRVAR
       
    38 #define PyDoc_STRVAR(name,str) static char name[] = str
       
    39 #endif
       
    40 
       
    41 #ifndef PyMODINIT_FUNC
       
    42 #define PyMODINIT_FUNC void
       
    43 #endif
       
    44 
       
    45 #ifndef PyBool_Check
       
    46 #define PyBool_Check(o)       0
       
    47 #define PyBool_FromLong       PyInt_FromLong
       
    48 #endif
       
    49 
       
    50 /* Starting with Tcl 8.4, many APIs offer const-correctness.  Unfortunately,
       
    51    making _tkinter correct for this API means to break earlier
       
    52    versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
       
    53    earlier versions. Once Tcl releases before 8.4 don't need to be supported
       
    54    anymore, this should go. */
       
    55 #define USE_COMPAT_CONST
       
    56 
       
    57 /* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
       
    58    it always; if Tcl is not threaded, the thread functions in
       
    59    Tcl are empty.  */
       
    60 #define TCL_THREADS
       
    61 
       
    62 #ifdef TK_FRAMEWORK
       
    63 #include <Tcl/tcl.h>
       
    64 #include <Tk/tk.h>
       
    65 #else
       
    66 #include <tcl.h>
       
    67 #include <tk.h>
       
    68 #endif
       
    69 
       
    70 /* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
       
    71 #ifndef CONST84_RETURN
       
    72 #define CONST84_RETURN
       
    73 #undef CONST
       
    74 #define CONST
       
    75 #endif
       
    76 
       
    77 #define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
       
    78 
       
    79 #if TKMAJORMINOR < 8002
       
    80 #error "Tk older than 8.2 not supported"
       
    81 #endif
       
    82 
       
    83 /* Unicode conversion assumes that Tcl_UniChar is two bytes.
       
    84    We cannot test this directly, so we test UTF-8 size instead,
       
    85    expecting that TCL_UTF_MAX is changed if Tcl ever supports
       
    86    either UTF-16 or UCS-4.  
       
    87    Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for 
       
    88    Tcl_Unichar. This is also ok as long as Python uses UCS-4,
       
    89    as well.
       
    90 */
       
    91 #if TCL_UTF_MAX != 3 && !(defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==6)
       
    92 #error "unsupported Tcl configuration"
       
    93 #endif
       
    94 
       
    95 #if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
       
    96 #define HAVE_CREATEFILEHANDLER
       
    97 #endif
       
    98 
       
    99 #ifdef HAVE_CREATEFILEHANDLER
       
   100 
       
   101 /* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere
       
   102    with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */
       
   103 #ifndef TCL_UNIX_FD
       
   104 #  ifdef TCL_WIN_SOCKET
       
   105 #    define TCL_UNIX_FD (! TCL_WIN_SOCKET)
       
   106 #  else
       
   107 #    define TCL_UNIX_FD 1
       
   108 #  endif
       
   109 #endif
       
   110 
       
   111 /* Tcl_CreateFileHandler() changed several times; these macros deal with the
       
   112    messiness.  In Tcl 8.0 and later, it is not available on Windows (and on
       
   113    Unix, only because Jack added it back); when available on Windows, it only
       
   114    applies to sockets. */
       
   115 
       
   116 #ifdef MS_WINDOWS
       
   117 #define FHANDLETYPE TCL_WIN_SOCKET
       
   118 #else
       
   119 #define FHANDLETYPE TCL_UNIX_FD
       
   120 #endif
       
   121 
       
   122 /* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
       
   123    which uses this to handle Tcl events while the user is typing commands. */
       
   124 
       
   125 #if FHANDLETYPE == TCL_UNIX_FD
       
   126 #define WAIT_FOR_STDIN
       
   127 #endif
       
   128 
       
   129 #endif /* HAVE_CREATEFILEHANDLER */
       
   130 
       
   131 #ifdef MS_WINDOWS
       
   132 #include <conio.h>
       
   133 #define WAIT_FOR_STDIN
       
   134 #endif
       
   135 
       
   136 #ifdef WITH_THREAD
       
   137 
       
   138 /* The threading situation is complicated.  Tcl is not thread-safe, except
       
   139    when configured with --enable-threads.
       
   140    So we need to use a lock around all uses of Tcl.  Previously, the Python
       
   141    interpreter lock was used for this.  However, this causes problems when
       
   142    other Python threads need to run while Tcl is blocked waiting for events.
       
   143 
       
   144    To solve this problem, a separate lock for Tcl is introduced.  Holding it
       
   145    is incompatible with holding Python's interpreter lock.  The following four
       
   146    macros manipulate both locks together.
       
   147 
       
   148    ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
       
   149    Py_END_ALLOW_THREADS.  They should be used whenever a call into Tcl is made
       
   150    that could call an event handler, or otherwise affect the state of a Tcl
       
   151    interpreter.  These assume that the surrounding code has the Python
       
   152    interpreter lock; inside the brackets, the Python interpreter lock has been
       
   153    released and the lock for Tcl has been acquired.
       
   154 
       
   155    Sometimes, it is necessary to have both the Python lock and the Tcl lock.
       
   156    (For example, when transferring data from the Tcl interpreter result to a
       
   157    Python string object.)  This can be done by using different macros to close
       
   158    the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
       
   159    the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
       
   160    releases the Tcl lock.
       
   161 
       
   162    By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
       
   163    handlers when the handler needs to use Python.  Such event handlers are
       
   164    entered while the lock for Tcl is held; the event handler presumably needs
       
   165    to use Python.  ENTER_PYTHON releases the lock for Tcl and acquires
       
   166    the Python interpreter lock, restoring the appropriate thread state, and
       
   167    LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
       
   168    for Tcl.  It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
       
   169    the code between ENTER_PYTHON and LEAVE_PYTHON.
       
   170 
       
   171    These locks expand to several statements and brackets; they should not be
       
   172    used in branches of if statements and the like.
       
   173 
       
   174    If Tcl is threaded, this approach won't work anymore. The Tcl interpreter is
       
   175    only valid in the thread that created it, and all Tk activity must happen in this
       
   176    thread, also. That means that the mainloop must be invoked in the thread that
       
   177    created the interpreter. Invoking commands from other threads is possible;
       
   178    _tkinter will queue an event for the interpreter thread, which will then
       
   179    execute the command and pass back the result. If the main thread is not in the
       
   180    mainloop, and invoking commands causes an exception; if the main loop is running
       
   181    but not processing events, the command invocation will block.
       
   182 
       
   183    In addition, for a threaded Tcl, a single global tcl_tstate won't be sufficient
       
   184    anymore, since multiple Tcl interpreters may simultaneously dispatch in different
       
   185    threads. So we use the Tcl TLS API.
       
   186 
       
   187 */
       
   188 
       
   189 static PyThread_type_lock tcl_lock = 0;
       
   190 
       
   191 #ifdef TCL_THREADS
       
   192 static Tcl_ThreadDataKey state_key;
       
   193 typedef PyThreadState *ThreadSpecificData;
       
   194 #define tcl_tstate (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*)))
       
   195 #else
       
   196 static PyThreadState *tcl_tstate = NULL;
       
   197 #endif
       
   198 
       
   199 #define ENTER_TCL \
       
   200 	{ PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
       
   201 	    if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
       
   202 
       
   203 #define LEAVE_TCL \
       
   204     tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
       
   205 
       
   206 #define ENTER_OVERLAP \
       
   207 	Py_END_ALLOW_THREADS
       
   208 
       
   209 #define LEAVE_OVERLAP_TCL \
       
   210 	tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
       
   211 
       
   212 #define ENTER_PYTHON \
       
   213 	{ PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
       
   214 	    if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
       
   215 
       
   216 #define LEAVE_PYTHON \
       
   217 	{ PyThreadState *tstate = PyEval_SaveThread(); \
       
   218 	    if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
       
   219 
       
   220 #define CHECK_TCL_APPARTMENT \
       
   221 	if (((TkappObject *)self)->threaded && \
       
   222 	    ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
       
   223 		PyErr_SetString(PyExc_RuntimeError, "Calling Tcl from different appartment"); \
       
   224 		return 0; \
       
   225 	}
       
   226 
       
   227 #else
       
   228 
       
   229 #define ENTER_TCL
       
   230 #define LEAVE_TCL
       
   231 #define ENTER_OVERLAP
       
   232 #define LEAVE_OVERLAP_TCL
       
   233 #define ENTER_PYTHON
       
   234 #define LEAVE_PYTHON
       
   235 #define CHECK_TCL_APPARTMENT
       
   236 
       
   237 #endif
       
   238 
       
   239 #ifndef FREECAST
       
   240 #define FREECAST (char *)
       
   241 #endif
       
   242 
       
   243 /**** Tkapp Object Declaration ****/
       
   244 
       
   245 static PyTypeObject Tkapp_Type;
       
   246 
       
   247 typedef struct {
       
   248 	PyObject_HEAD
       
   249 	Tcl_Interp *interp;
       
   250 	int wantobjects;
       
   251 	int threaded; /* True if tcl_platform[threaded] */
       
   252 	Tcl_ThreadId thread_id;
       
   253 	int dispatching;
       
   254 	/* We cannot include tclInt.h, as this is internal.
       
   255 	   So we cache interesting types here. */
       
   256 	Tcl_ObjType *BooleanType;
       
   257 	Tcl_ObjType *ByteArrayType;
       
   258 	Tcl_ObjType *DoubleType;
       
   259 	Tcl_ObjType *IntType;
       
   260 	Tcl_ObjType *ListType;
       
   261 	Tcl_ObjType *ProcBodyType;
       
   262 	Tcl_ObjType *StringType;
       
   263 } TkappObject;
       
   264 
       
   265 #define Tkapp_Check(v) (Py_TYPE(v) == &Tkapp_Type)
       
   266 #define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
       
   267 #define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
       
   268 
       
   269 #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
       
   270 (void *) v, Py_REFCNT(v)))
       
   271 
       
   272 
       
   273 
       
   274 /**** Error Handling ****/
       
   275 
       
   276 static PyObject *Tkinter_TclError;
       
   277 static int quitMainLoop = 0;
       
   278 static int errorInCmd = 0;
       
   279 static PyObject *excInCmd;
       
   280 static PyObject *valInCmd;
       
   281 static PyObject *trbInCmd;
       
   282 
       
   283 
       
   284 
       
   285 static PyObject *
       
   286 Tkinter_Error(PyObject *v)
       
   287 {
       
   288 	PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
       
   289 	return NULL;
       
   290 }
       
   291 
       
   292 
       
   293 
       
   294 /**** Utils ****/
       
   295 
       
   296 static int Tkinter_busywaitinterval = 20;
       
   297 
       
   298 #ifdef WITH_THREAD
       
   299 #ifndef MS_WINDOWS
       
   300 
       
   301 /* Millisecond sleep() for Unix platforms. */
       
   302 
       
   303 static void
       
   304 Sleep(int milli)
       
   305 {
       
   306 	/* XXX Too bad if you don't have select(). */
       
   307 	struct timeval t;
       
   308 	t.tv_sec = milli/1000;
       
   309 	t.tv_usec = (milli%1000) * 1000;
       
   310 	select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
       
   311 }
       
   312 #endif /* MS_WINDOWS */
       
   313 
       
   314 /* Wait up to 1s for the mainloop to come up. */
       
   315 
       
   316 static int
       
   317 WaitForMainloop(TkappObject* self)
       
   318 {
       
   319 	int i;
       
   320 	for (i = 0; i < 10; i++) {
       
   321 		if (self->dispatching)
       
   322 			return 1;
       
   323 		Py_BEGIN_ALLOW_THREADS
       
   324 		Sleep(100);
       
   325 		Py_END_ALLOW_THREADS
       
   326 	}
       
   327 	if (self->dispatching)
       
   328 		return 1;
       
   329 	PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
       
   330 	return 0;
       
   331 }
       
   332 #endif /* WITH_THREAD */
       
   333 
       
   334 
       
   335 static char *
       
   336 AsString(PyObject *value, PyObject *tmp)
       
   337 {
       
   338 	if (PyString_Check(value))
       
   339 		return PyString_AsString(value);
       
   340 #ifdef Py_USING_UNICODE
       
   341 	else if (PyUnicode_Check(value)) {
       
   342 		PyObject *v = PyUnicode_AsUTF8String(value);
       
   343 		if (v == NULL)
       
   344 			return NULL;
       
   345 		if (PyList_Append(tmp, v) != 0) {
       
   346 			Py_DECREF(v);
       
   347 			return NULL;
       
   348 		}
       
   349 		Py_DECREF(v);
       
   350 		return PyString_AsString(v);
       
   351 	}
       
   352 #endif
       
   353 	else {
       
   354 		PyObject *v = PyObject_Str(value);
       
   355 		if (v == NULL)
       
   356 			return NULL;
       
   357 		if (PyList_Append(tmp, v) != 0) {
       
   358 			Py_DECREF(v);
       
   359 			return NULL;
       
   360 		}
       
   361 		Py_DECREF(v);
       
   362 		return PyString_AsString(v);
       
   363 	}
       
   364 }
       
   365 
       
   366 
       
   367 
       
   368 #define ARGSZ 64
       
   369 
       
   370 static char *
       
   371 Merge(PyObject *args)
       
   372 {
       
   373 	PyObject *tmp = NULL;
       
   374 	char *argvStore[ARGSZ];
       
   375 	char **argv = NULL;
       
   376 	int fvStore[ARGSZ];
       
   377 	int *fv = NULL;
       
   378 	int argc = 0, fvc = 0, i;
       
   379 	char *res = NULL;
       
   380 
       
   381 	if (!(tmp = PyList_New(0)))
       
   382 	    return NULL;
       
   383 
       
   384 	argv = argvStore;
       
   385 	fv = fvStore;
       
   386 
       
   387 	if (args == NULL)
       
   388 		argc = 0;
       
   389 
       
   390 	else if (!PyTuple_Check(args)) {
       
   391 		argc = 1;
       
   392 		fv[0] = 0;
       
   393 		if (!(argv[0] = AsString(args, tmp)))
       
   394 			goto finally;
       
   395 	}
       
   396 	else {
       
   397 		argc = PyTuple_Size(args);
       
   398 
       
   399 		if (argc > ARGSZ) {
       
   400 			argv = (char **)ckalloc(argc * sizeof(char *));
       
   401 			fv = (int *)ckalloc(argc * sizeof(int));
       
   402 			if (argv == NULL || fv == NULL) {
       
   403 				PyErr_NoMemory();
       
   404 				goto finally;
       
   405 			}
       
   406 		}
       
   407 
       
   408 		for (i = 0; i < argc; i++) {
       
   409 			PyObject *v = PyTuple_GetItem(args, i);
       
   410 			if (PyTuple_Check(v)) {
       
   411 				fv[i] = 1;
       
   412 				if (!(argv[i] = Merge(v)))
       
   413 					goto finally;
       
   414 				fvc++;
       
   415 			}
       
   416 			else if (v == Py_None) {
       
   417 				argc = i;
       
   418 				break;
       
   419 			}
       
   420 			else {
       
   421 				fv[i] = 0;
       
   422 				if (!(argv[i] = AsString(v, tmp)))
       
   423 					goto finally;
       
   424 				fvc++;
       
   425 			}
       
   426 		}
       
   427 	}
       
   428 	res = Tcl_Merge(argc, argv);
       
   429 	if (res == NULL)
       
   430 		PyErr_SetString(Tkinter_TclError, "merge failed");
       
   431 
       
   432   finally:
       
   433 	for (i = 0; i < fvc; i++)
       
   434 		if (fv[i]) {
       
   435 			ckfree(argv[i]);
       
   436 		}
       
   437 	if (argv != argvStore)
       
   438 		ckfree(FREECAST argv);
       
   439 	if (fv != fvStore)
       
   440 		ckfree(FREECAST fv);
       
   441 
       
   442 	Py_DECREF(tmp);
       
   443 	return res;
       
   444 }
       
   445 
       
   446 
       
   447 
       
   448 static PyObject *
       
   449 Split(char *list)
       
   450 {
       
   451 	int argc;
       
   452 	char **argv;
       
   453 	PyObject *v;
       
   454 
       
   455 	if (list == NULL) {
       
   456 		Py_INCREF(Py_None);
       
   457 		return Py_None;
       
   458 	}
       
   459 
       
   460 	if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
       
   461 		/* Not a list.
       
   462 		 * Could be a quoted string containing funnies, e.g. {"}.
       
   463 		 * Return the string itself.
       
   464 		 */
       
   465 		return PyString_FromString(list);
       
   466 	}
       
   467 
       
   468 	if (argc == 0)
       
   469 		v = PyString_FromString("");
       
   470 	else if (argc == 1)
       
   471 		v = PyString_FromString(argv[0]);
       
   472 	else if ((v = PyTuple_New(argc)) != NULL) {
       
   473 		int i;
       
   474 		PyObject *w;
       
   475 
       
   476 		for (i = 0; i < argc; i++) {
       
   477 			if ((w = Split(argv[i])) == NULL) {
       
   478 				Py_DECREF(v);
       
   479 				v = NULL;
       
   480 				break;
       
   481 			}
       
   482 			PyTuple_SetItem(v, i, w);
       
   483 		}
       
   484 	}
       
   485 	Tcl_Free(FREECAST argv);
       
   486 	return v;
       
   487 }
       
   488 
       
   489 /* In some cases, Tcl will still return strings that are supposed to be
       
   490    lists. SplitObj walks through a nested tuple, finding string objects that
       
   491    need to be split. */
       
   492 
       
   493 static PyObject *
       
   494 SplitObj(PyObject *arg)
       
   495 {
       
   496 	if (PyTuple_Check(arg)) {
       
   497 		int i, size;
       
   498 		PyObject *elem, *newelem, *result;
       
   499 
       
   500 		size = PyTuple_Size(arg);
       
   501 		result = NULL;
       
   502 		/* Recursively invoke SplitObj for all tuple items.
       
   503 		   If this does not return a new object, no action is
       
   504 		   needed. */
       
   505 		for(i = 0; i < size; i++) {
       
   506 			elem = PyTuple_GetItem(arg, i);
       
   507 			newelem = SplitObj(elem);
       
   508 			if (!newelem) {
       
   509 				Py_XDECREF(result);
       
   510 				return NULL;
       
   511 			}
       
   512 			if (!result) {
       
   513 				int k;
       
   514 				if (newelem == elem) {
       
   515 					Py_DECREF(newelem);
       
   516 					continue;
       
   517 				}
       
   518 				result = PyTuple_New(size);
       
   519 				if (!result)
       
   520 					return NULL;
       
   521 				for(k = 0; k < i; k++) {
       
   522 					elem = PyTuple_GetItem(arg, k);
       
   523 					Py_INCREF(elem);
       
   524 					PyTuple_SetItem(result, k, elem);
       
   525 				}
       
   526 			}
       
   527 			PyTuple_SetItem(result, i, newelem);
       
   528 		}
       
   529 		if (result)
       
   530 			return result;
       
   531 		/* Fall through, returning arg. */
       
   532 	}
       
   533 	else if (PyString_Check(arg)) {
       
   534 		int argc;
       
   535 		char **argv;
       
   536 		char *list = PyString_AsString(arg);
       
   537 
       
   538 		if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
       
   539 			Py_INCREF(arg);
       
   540 			return arg;
       
   541 		}
       
   542 		Tcl_Free(FREECAST argv);
       
   543 		if (argc > 1)
       
   544 			return Split(PyString_AsString(arg));
       
   545 		/* Fall through, returning arg. */
       
   546 	}
       
   547 	Py_INCREF(arg);
       
   548 	return arg;
       
   549 }
       
   550 
       
   551 
       
   552 /**** Tkapp Object ****/
       
   553 
       
   554 #ifndef WITH_APPINIT
       
   555 int
       
   556 Tcl_AppInit(Tcl_Interp *interp)
       
   557 {
       
   558 	Tk_Window main;
       
   559 	const char * _tkinter_skip_tk_init;
       
   560 
       
   561 	if (Tcl_Init(interp) == TCL_ERROR) {
       
   562 		PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
       
   563 		return TCL_ERROR;
       
   564 	}
       
   565 	_tkinter_skip_tk_init =	Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
       
   566 	if (_tkinter_skip_tk_init == NULL || strcmp(_tkinter_skip_tk_init, "1")	!= 0) {
       
   567 		main = Tk_MainWindow(interp);
       
   568 		if (Tk_Init(interp) == TCL_ERROR) {
       
   569 			PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
       
   570 			return TCL_ERROR;
       
   571 		}
       
   572 	}
       
   573 	return TCL_OK;
       
   574 }
       
   575 #endif /* !WITH_APPINIT */
       
   576 
       
   577 
       
   578 
       
   579 
       
   580 /* Initialize the Tk application; see the `main' function in
       
   581  * `tkMain.c'.
       
   582  */
       
   583 
       
   584 static void EnableEventHook(void); /* Forward */
       
   585 static void DisableEventHook(void); /* Forward */
       
   586 
       
   587 static TkappObject *
       
   588 Tkapp_New(char *screenName, char *baseName, char *className,
       
   589 	  int interactive, int wantobjects, int	wantTk, int sync, char *use)
       
   590 {
       
   591 	TkappObject *v;
       
   592 	char *argv0;
       
   593 
       
   594 	v = PyObject_New(TkappObject, &Tkapp_Type);
       
   595 	if (v == NULL)
       
   596 		return NULL;
       
   597 
       
   598 	v->interp = Tcl_CreateInterp();
       
   599 	v->wantobjects = wantobjects;
       
   600 	v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
       
   601 				    TCL_GLOBAL_ONLY) != NULL;
       
   602 	v->thread_id = Tcl_GetCurrentThread();
       
   603 	v->dispatching = 0;
       
   604 
       
   605 #ifndef TCL_THREADS
       
   606 	if (v->threaded) {
       
   607 	    PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
       
   608 	    Py_DECREF(v);
       
   609 	    return 0;
       
   610 	}
       
   611 #endif
       
   612 #ifdef WITH_THREAD
       
   613 	if (v->threaded && tcl_lock) {
       
   614 	    /* If Tcl is threaded, we don't need the lock. */
       
   615 	    PyThread_free_lock(tcl_lock);
       
   616 	    tcl_lock = NULL;
       
   617 	}
       
   618 #endif
       
   619 
       
   620 	v->BooleanType = Tcl_GetObjType("boolean");
       
   621 	v->ByteArrayType = Tcl_GetObjType("bytearray");
       
   622 	v->DoubleType = Tcl_GetObjType("double");
       
   623 	v->IntType = Tcl_GetObjType("int");
       
   624 	v->ListType = Tcl_GetObjType("list");
       
   625 	v->ProcBodyType = Tcl_GetObjType("procbody");
       
   626 	v->StringType = Tcl_GetObjType("string");
       
   627 
       
   628 	/* Delete the 'exit' command, which can screw things up */
       
   629 	Tcl_DeleteCommand(v->interp, "exit");
       
   630 
       
   631 	if (screenName != NULL)
       
   632 		Tcl_SetVar2(v->interp, "env", "DISPLAY",
       
   633 			    screenName, TCL_GLOBAL_ONLY);
       
   634 
       
   635 	if (interactive)
       
   636 		Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
       
   637 	else
       
   638 		Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
       
   639 
       
   640 	/* This is used to get the application class for Tk 4.1 and up */
       
   641 	argv0 = (char*)ckalloc(strlen(className) + 1);
       
   642 	if (!argv0) {
       
   643 		PyErr_NoMemory();
       
   644 		Py_DECREF(v);
       
   645 		return NULL;
       
   646 	}
       
   647 
       
   648 	strcpy(argv0, className);
       
   649 	if (isupper(Py_CHARMASK(argv0[0])))
       
   650 		argv0[0] = tolower(Py_CHARMASK(argv0[0]));
       
   651 	Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
       
   652 	ckfree(argv0);
       
   653 
       
   654 	if (! wantTk) {
       
   655 	    Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1",	TCL_GLOBAL_ONLY);
       
   656 	}
       
   657 
       
   658 	/* some initial arguments need to be in argv */
       
   659 	if (sync || use) {
       
   660 		char *args;
       
   661 		int len = 0;
       
   662 
       
   663 		if (sync)
       
   664 			len += sizeof "-sync";
       
   665 		if (use)
       
   666 			len += strlen(use) + sizeof "-use ";
       
   667 
       
   668 		args = (char*)ckalloc(len);
       
   669 		if (!args) {
       
   670 			PyErr_NoMemory();
       
   671 			Py_DECREF(v);
       
   672 			return NULL;
       
   673 		}
       
   674 
       
   675 		args[0] = '\0';
       
   676 		if (sync)
       
   677 			strcat(args, "-sync");
       
   678 		if (use) {
       
   679 			if (sync)
       
   680 				strcat(args, " ");
       
   681 			strcat(args, "-use ");
       
   682 			strcat(args, use);
       
   683 		}
       
   684 
       
   685 		Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
       
   686 		ckfree(args);
       
   687 	}
       
   688 
       
   689 	if (Tcl_AppInit(v->interp) != TCL_OK) {
       
   690 		PyObject *result = Tkinter_Error((PyObject *)v);
       
   691 		Py_DECREF((PyObject *)v);
       
   692 		return (TkappObject *)result;
       
   693 	}
       
   694 
       
   695 	EnableEventHook();
       
   696 
       
   697 	return v;
       
   698 }
       
   699 
       
   700 
       
   701 static void
       
   702 Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
       
   703 		 Tcl_Condition *cond, Tcl_Mutex *mutex)
       
   704 {
       
   705 	Py_BEGIN_ALLOW_THREADS;
       
   706 	Tcl_MutexLock(mutex);
       
   707 	Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
       
   708 	Tcl_ThreadAlert(self->thread_id);
       
   709 	Tcl_ConditionWait(cond, mutex, NULL);
       
   710 	Tcl_MutexUnlock(mutex);
       
   711 	Py_END_ALLOW_THREADS
       
   712 }
       
   713 
       
   714 
       
   715 /** Tcl Eval **/
       
   716 
       
   717 typedef struct {
       
   718 	PyObject_HEAD
       
   719 	Tcl_Obj *value;
       
   720 	PyObject *string; /* This cannot cause cycles. */
       
   721 } PyTclObject;
       
   722 
       
   723 staticforward PyTypeObject PyTclObject_Type;
       
   724 #define PyTclObject_Check(v)	((v)->ob_type == &PyTclObject_Type)
       
   725 
       
   726 static PyObject *
       
   727 newPyTclObject(Tcl_Obj *arg)
       
   728 {
       
   729 	PyTclObject *self;
       
   730 	self = PyObject_New(PyTclObject, &PyTclObject_Type);
       
   731 	if (self == NULL)
       
   732 		return NULL;
       
   733 	Tcl_IncrRefCount(arg);
       
   734 	self->value = arg;
       
   735 	self->string = NULL;
       
   736 	return (PyObject*)self;
       
   737 }
       
   738 
       
   739 static void
       
   740 PyTclObject_dealloc(PyTclObject *self)
       
   741 {
       
   742 	Tcl_DecrRefCount(self->value);
       
   743 	Py_XDECREF(self->string);
       
   744 	PyObject_Del(self);
       
   745 }
       
   746 
       
   747 static PyObject *
       
   748 PyTclObject_str(PyTclObject *self)
       
   749 {
       
   750 	if (self->string && PyString_Check(self->string)) {
       
   751 		Py_INCREF(self->string);
       
   752 		return self->string;
       
   753 	}
       
   754 	/* XXX Could cache value if it is an ASCII string. */
       
   755 	return PyString_FromString(Tcl_GetString(self->value));
       
   756 }
       
   757 
       
   758 static char*
       
   759 PyTclObject_TclString(PyObject *self)
       
   760 {
       
   761 	return Tcl_GetString(((PyTclObject*)self)->value);
       
   762 }
       
   763 
       
   764 /* Like _str, but create Unicode if necessary. */
       
   765 PyDoc_STRVAR(PyTclObject_string__doc__, 
       
   766 "the string representation of this object, either as string or Unicode");
       
   767 
       
   768 static PyObject *
       
   769 PyTclObject_string(PyTclObject *self, void *ignored)
       
   770 {
       
   771 	char *s;
       
   772 	int i, len;
       
   773 	if (!self->string) {
       
   774 		s = Tcl_GetStringFromObj(self->value, &len);
       
   775 		for (i = 0; i < len; i++)
       
   776 			if (s[i] & 0x80)
       
   777 				break;
       
   778 #ifdef Py_USING_UNICODE
       
   779 		if (i == len)
       
   780 			/* It is an ASCII string. */
       
   781 			self->string = PyString_FromStringAndSize(s, len);
       
   782 		else {
       
   783 			self->string = PyUnicode_DecodeUTF8(s, len, "strict");
       
   784 			if (!self->string) {
       
   785 				PyErr_Clear();
       
   786 				self->string = PyString_FromStringAndSize(s, len);
       
   787 			}
       
   788 		}
       
   789 #else
       
   790 		self->string = PyString_FromStringAndSize(s, len);
       
   791 #endif
       
   792 		if (!self->string)
       
   793 			return NULL;
       
   794 	}
       
   795 	Py_INCREF(self->string);
       
   796 	return self->string;
       
   797 }
       
   798 
       
   799 #ifdef Py_USING_UNICODE
       
   800 PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode");
       
   801 
       
   802 static PyObject *
       
   803 PyTclObject_unicode(PyTclObject *self, void *ignored)
       
   804 {
       
   805 	char *s;
       
   806 	int len;
       
   807 	if (self->string && PyUnicode_Check(self->string)) {
       
   808 		Py_INCREF(self->string);
       
   809 		return self->string;
       
   810 	}
       
   811 	/* XXX Could chache result if it is non-ASCII. */
       
   812 	s = Tcl_GetStringFromObj(self->value, &len);
       
   813 	return PyUnicode_DecodeUTF8(s, len, "strict");
       
   814 }
       
   815 #endif
       
   816 
       
   817 static PyObject *
       
   818 PyTclObject_repr(PyTclObject *self)
       
   819 {
       
   820 	char buf[50];
       
   821 	PyOS_snprintf(buf, 50, "<%s object at %p>",
       
   822 		      self->value->typePtr->name, self->value);
       
   823 	return PyString_FromString(buf);
       
   824 }
       
   825 
       
   826 static int
       
   827 PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
       
   828 {
       
   829 	int res;
       
   830 	res = strcmp(Tcl_GetString(self->value),
       
   831 		     Tcl_GetString(other->value));
       
   832 	if (res < 0) return -1;
       
   833 	if (res > 0) return 1;
       
   834 	return 0;
       
   835 }
       
   836 
       
   837 PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
       
   838 
       
   839 static PyObject*
       
   840 get_typename(PyTclObject* obj, void* ignored)
       
   841 {
       
   842 	return PyString_FromString(obj->value->typePtr->name);
       
   843 }
       
   844 
       
   845 
       
   846 static PyGetSetDef PyTclObject_getsetlist[] = {
       
   847 	{"typename", (getter)get_typename, NULL, get_typename__doc__},
       
   848 	{"string", (getter)PyTclObject_string, NULL, 
       
   849 	 PyTclObject_string__doc__},
       
   850 	{0},
       
   851 };
       
   852 
       
   853 static PyMethodDef PyTclObject_methods[] = {
       
   854 #ifdef Py_USING_UNICODE
       
   855 	{"__unicode__",	(PyCFunction)PyTclObject_unicode, METH_NOARGS,
       
   856 	PyTclObject_unicode__doc__},
       
   857 #endif
       
   858 	{0}
       
   859 };
       
   860 
       
   861 statichere PyTypeObject PyTclObject_Type = {
       
   862 	PyObject_HEAD_INIT(NULL)
       
   863 	0,			/*ob_size*/
       
   864 	"_tkinter.Tcl_Obj",		/*tp_name*/
       
   865 	sizeof(PyTclObject),	/*tp_basicsize*/
       
   866 	0,			/*tp_itemsize*/
       
   867 	/* methods */
       
   868 	(destructor)PyTclObject_dealloc, /*tp_dealloc*/
       
   869 	0,			/*tp_print*/
       
   870 	0,			/*tp_getattr*/
       
   871 	0,			/*tp_setattr*/
       
   872 	(cmpfunc)PyTclObject_cmp,	/*tp_compare*/
       
   873 	(reprfunc)PyTclObject_repr,	/*tp_repr*/
       
   874 	0,			/*tp_as_number*/
       
   875 	0,			/*tp_as_sequence*/
       
   876 	0,			/*tp_as_mapping*/
       
   877 	0,			/*tp_hash*/
       
   878         0,                      /*tp_call*/
       
   879         (reprfunc)PyTclObject_str,        /*tp_str*/
       
   880         PyObject_GenericGetAttr,/*tp_getattro*/
       
   881         0,                      /*tp_setattro*/
       
   882         0,                      /*tp_as_buffer*/
       
   883         Py_TPFLAGS_DEFAULT,     /*tp_flags*/
       
   884         0,                      /*tp_doc*/
       
   885         0,                      /*tp_traverse*/
       
   886         0,                      /*tp_clear*/
       
   887         0,                      /*tp_richcompare*/
       
   888         0,                      /*tp_weaklistoffset*/
       
   889         0,                      /*tp_iter*/
       
   890         0,                      /*tp_iternext*/
       
   891         PyTclObject_methods,    /*tp_methods*/
       
   892         0,			/*tp_members*/
       
   893         PyTclObject_getsetlist, /*tp_getset*/
       
   894         0,                      /*tp_base*/
       
   895         0,                      /*tp_dict*/
       
   896         0,                      /*tp_descr_get*/
       
   897         0,                      /*tp_descr_set*/
       
   898         0,                      /*tp_dictoffset*/
       
   899         0,                      /*tp_init*/
       
   900         0,                      /*tp_alloc*/
       
   901         0,                      /*tp_new*/
       
   902         0,                      /*tp_free*/
       
   903         0,                      /*tp_is_gc*/
       
   904 };
       
   905 
       
   906 static Tcl_Obj*
       
   907 AsObj(PyObject *value)
       
   908 {
       
   909 	Tcl_Obj *result;
       
   910 
       
   911 	if (PyString_Check(value))
       
   912 		return Tcl_NewStringObj(PyString_AS_STRING(value),
       
   913 					PyString_GET_SIZE(value));
       
   914 	else if (PyBool_Check(value))
       
   915 		return Tcl_NewBooleanObj(PyObject_IsTrue(value));
       
   916 	else if (PyInt_Check(value))
       
   917 		return Tcl_NewLongObj(PyInt_AS_LONG(value));
       
   918 	else if (PyFloat_Check(value))
       
   919 		return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
       
   920 	else if (PyTuple_Check(value)) {
       
   921 		Tcl_Obj **argv = (Tcl_Obj**)
       
   922 			ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
       
   923 		int i;
       
   924 		if(!argv)
       
   925 		  return 0;
       
   926 		for(i=0;i<PyTuple_Size(value);i++)
       
   927 		  argv[i] = AsObj(PyTuple_GetItem(value,i));
       
   928 		result = Tcl_NewListObj(PyTuple_Size(value), argv);
       
   929 		ckfree(FREECAST argv);
       
   930 		return result;
       
   931 	}
       
   932 #ifdef Py_USING_UNICODE
       
   933 	else if (PyUnicode_Check(value)) {
       
   934 		Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
       
   935 		Py_ssize_t size = PyUnicode_GET_SIZE(value);
       
   936 		/* This #ifdef assumes that Tcl uses UCS-2.
       
   937 		   See TCL_UTF_MAX test above. */
       
   938 #if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
       
   939 		Tcl_UniChar *outbuf = NULL;
       
   940 		Py_ssize_t i;
       
   941 		size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
       
   942 		if (allocsize >= size)
       
   943 			outbuf = (Tcl_UniChar*)ckalloc(allocsize);
       
   944 		/* Else overflow occurred, and we take the next exit */
       
   945 		if (!outbuf) {
       
   946 			PyErr_NoMemory();
       
   947 			return NULL;
       
   948 		}
       
   949 		for (i = 0; i < size; i++) {
       
   950 			if (inbuf[i] >= 0x10000) {
       
   951 				/* Tcl doesn't do UTF-16, yet. */
       
   952 				PyErr_SetString(PyExc_ValueError,
       
   953 						"unsupported character");
       
   954 				ckfree(FREECAST outbuf);
       
   955 				return NULL;
       
   956 			}
       
   957 			outbuf[i] = inbuf[i];
       
   958 		}
       
   959 		result = Tcl_NewUnicodeObj(outbuf, size);
       
   960 		ckfree(FREECAST outbuf);
       
   961 		return result;
       
   962 #else
       
   963 		return Tcl_NewUnicodeObj(inbuf, size);
       
   964 #endif
       
   965 
       
   966 	}
       
   967 #endif
       
   968 	else if(PyTclObject_Check(value)) {
       
   969 		Tcl_Obj *v = ((PyTclObject*)value)->value;
       
   970 		Tcl_IncrRefCount(v);
       
   971 		return v;
       
   972 	} 
       
   973 	else {
       
   974 		PyObject *v = PyObject_Str(value);
       
   975 		if (!v)
       
   976 			return 0;
       
   977 		result = AsObj(v);
       
   978 		Py_DECREF(v);
       
   979 		return result;
       
   980 	}
       
   981 }
       
   982 
       
   983 static PyObject*
       
   984 FromObj(PyObject* tkapp, Tcl_Obj *value)
       
   985 {
       
   986 	PyObject *result = NULL;
       
   987 	TkappObject *app = (TkappObject*)tkapp;
       
   988 
       
   989 	if (value->typePtr == NULL) {
       
   990 		/* If the result contains any bytes with the top bit set,
       
   991 		   it's UTF-8 and we should decode it to Unicode */
       
   992 #ifdef Py_USING_UNICODE
       
   993 		int i;
       
   994 		char *s = value->bytes;
       
   995 		int len = value->length;
       
   996 		for (i = 0; i < len; i++) {
       
   997 			if (value->bytes[i] & 0x80)
       
   998 				break;
       
   999 		}
       
  1000 
       
  1001 		if (i == value->length)
       
  1002 			result = PyString_FromStringAndSize(s, len);
       
  1003 		else {
       
  1004 			/* Convert UTF-8 to Unicode string */
       
  1005 			result = PyUnicode_DecodeUTF8(s, len, "strict");
       
  1006 			if (result == NULL) {
       
  1007 				PyErr_Clear();
       
  1008 				result = PyString_FromStringAndSize(s, len);
       
  1009 			}
       
  1010 		}
       
  1011 #else
       
  1012 		result = PyString_FromStringAndSize(value->bytes, value->length);
       
  1013 #endif
       
  1014 		return result;
       
  1015 	}
       
  1016 
       
  1017 	if (value->typePtr == app->BooleanType) {
       
  1018 		result = value->internalRep.longValue ? Py_True : Py_False;
       
  1019 		Py_INCREF(result);
       
  1020 		return result;
       
  1021 	}
       
  1022 
       
  1023 	if (value->typePtr == app->ByteArrayType) {
       
  1024 		int size;
       
  1025 		char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
       
  1026 		return PyString_FromStringAndSize(data, size);
       
  1027 	}
       
  1028 
       
  1029 	if (value->typePtr == app->DoubleType) {
       
  1030 		return PyFloat_FromDouble(value->internalRep.doubleValue);
       
  1031 	}
       
  1032 
       
  1033 	if (value->typePtr == app->IntType) {
       
  1034 		return PyInt_FromLong(value->internalRep.longValue);
       
  1035 	}
       
  1036 
       
  1037 	if (value->typePtr == app->ListType) {
       
  1038 		int size;
       
  1039 		int i, status;
       
  1040 		PyObject *elem;
       
  1041 		Tcl_Obj *tcl_elem;
       
  1042 
       
  1043 		status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
       
  1044 		if (status == TCL_ERROR)
       
  1045 			return Tkinter_Error(tkapp);
       
  1046 		result = PyTuple_New(size);
       
  1047 		if (!result)
       
  1048 			return NULL;
       
  1049 		for (i = 0; i < size; i++) {
       
  1050 			status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
       
  1051 						  value, i, &tcl_elem);
       
  1052 			if (status == TCL_ERROR) {
       
  1053 				Py_DECREF(result);
       
  1054 				return Tkinter_Error(tkapp);
       
  1055 			}
       
  1056 			elem = FromObj(tkapp, tcl_elem);
       
  1057 			if (!elem) {
       
  1058 				Py_DECREF(result);
       
  1059 				return NULL;
       
  1060 			}
       
  1061 			PyTuple_SetItem(result, i, elem);
       
  1062 		}
       
  1063 		return result;
       
  1064 	}
       
  1065 
       
  1066 	if (value->typePtr == app->ProcBodyType) {
       
  1067 	  /* fall through: return tcl object. */
       
  1068 	}
       
  1069 
       
  1070 	if (value->typePtr == app->StringType) {
       
  1071 #ifdef Py_USING_UNICODE
       
  1072 #if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
       
  1073 		PyObject *result;
       
  1074 		int size;
       
  1075 		Tcl_UniChar *input;
       
  1076 		Py_UNICODE *output;
       
  1077 
       
  1078 		size = Tcl_GetCharLength(value);
       
  1079 		result = PyUnicode_FromUnicode(NULL, size);
       
  1080 		if (!result)
       
  1081 			return NULL;
       
  1082 		input = Tcl_GetUnicode(value);
       
  1083 		output = PyUnicode_AS_UNICODE(result);
       
  1084 		while (size--)
       
  1085 			*output++ = *input++;
       
  1086 		return result;
       
  1087 #else
       
  1088 		return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
       
  1089 					     Tcl_GetCharLength(value));
       
  1090 #endif
       
  1091 #else
       
  1092 		int size;
       
  1093 		char *c;
       
  1094 		c = Tcl_GetStringFromObj(value, &size);
       
  1095 		return PyString_FromStringAndSize(c, size);
       
  1096 #endif
       
  1097 	}
       
  1098 
       
  1099 	return newPyTclObject(value);
       
  1100 }
       
  1101 
       
  1102 /* This mutex synchronizes inter-thread command calls. */
       
  1103 
       
  1104 TCL_DECLARE_MUTEX(call_mutex)
       
  1105 
       
  1106 typedef struct Tkapp_CallEvent {
       
  1107 	Tcl_Event ev;	     /* Must be first */
       
  1108 	TkappObject *self;
       
  1109 	PyObject *args;
       
  1110 	int flags;
       
  1111 	PyObject **res;
       
  1112 	PyObject **exc_type, **exc_value, **exc_tb;
       
  1113 	Tcl_Condition done;
       
  1114 } Tkapp_CallEvent;
       
  1115 
       
  1116 void
       
  1117 Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
       
  1118 {
       
  1119 	int i;
       
  1120 	for (i = 0; i < objc; i++)
       
  1121 		Tcl_DecrRefCount(objv[i]);
       
  1122 	if (objv != objStore)
       
  1123 		ckfree(FREECAST objv);
       
  1124 }
       
  1125 
       
  1126 /* Convert Python objects to Tcl objects. This must happen in the
       
  1127    interpreter thread, which may or may not be the calling thread. */
       
  1128 
       
  1129 static Tcl_Obj**
       
  1130 Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
       
  1131 {
       
  1132 	Tcl_Obj **objv = objStore;
       
  1133 	int objc = 0, i;
       
  1134 	if (args == NULL)
       
  1135 		/* do nothing */;
       
  1136 
       
  1137 	else if (!PyTuple_Check(args)) {
       
  1138 		objv[0] = AsObj(args);
       
  1139 		if (objv[0] == 0)
       
  1140 			goto finally;
       
  1141 		objc = 1;
       
  1142 		Tcl_IncrRefCount(objv[0]);
       
  1143 	}
       
  1144 	else {
       
  1145 		objc = PyTuple_Size(args);
       
  1146 
       
  1147 		if (objc > ARGSZ) {
       
  1148 			objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
       
  1149 			if (objv == NULL) {
       
  1150 				PyErr_NoMemory();
       
  1151 				objc = 0;
       
  1152 				goto finally;
       
  1153 			}
       
  1154 		}
       
  1155 
       
  1156 		for (i = 0; i < objc; i++) {
       
  1157 			PyObject *v = PyTuple_GetItem(args, i);
       
  1158 			if (v == Py_None) {
       
  1159 				objc = i;
       
  1160 				break;
       
  1161 			}
       
  1162 			objv[i] = AsObj(v);
       
  1163 			if (!objv[i]) {
       
  1164 				/* Reset objc, so it attempts to clear
       
  1165 				   objects only up to i. */
       
  1166 				objc = i;
       
  1167 				goto finally;
       
  1168 			}
       
  1169 			Tcl_IncrRefCount(objv[i]);
       
  1170 		}
       
  1171 	}
       
  1172 	*pobjc = objc;
       
  1173 	return objv;
       
  1174 finally:
       
  1175 	Tkapp_CallDeallocArgs(objv, objStore, objc);
       
  1176 	return NULL;
       
  1177 }
       
  1178 
       
  1179 /* Convert the results of a command call into a Python objects. */
       
  1180 
       
  1181 static PyObject*
       
  1182 Tkapp_CallResult(TkappObject *self)
       
  1183 {
       
  1184 	PyObject *res = NULL;
       
  1185 	if(self->wantobjects) {
       
  1186 		Tcl_Obj *value = Tcl_GetObjResult(self->interp);
       
  1187 		/* Not sure whether the IncrRef is necessary, but something
       
  1188 		   may overwrite the interpreter result while we are
       
  1189 		   converting it. */
       
  1190 		Tcl_IncrRefCount(value);
       
  1191 		res = FromObj((PyObject*)self, value);
       
  1192 		Tcl_DecrRefCount(value);
       
  1193 	} else {
       
  1194 		const char *s = Tcl_GetStringResult(self->interp);
       
  1195 		const char *p = s;
       
  1196 
       
  1197 		/* If the result contains any bytes with the top bit set,
       
  1198 		   it's UTF-8 and we should decode it to Unicode */
       
  1199 #ifdef Py_USING_UNICODE
       
  1200 		while (*p != '\0') {
       
  1201 			if (*p & 0x80)
       
  1202 				break;
       
  1203 			p++;
       
  1204 		}
       
  1205 
       
  1206 		if (*p == '\0')
       
  1207 			res = PyString_FromStringAndSize(s, (int)(p-s));
       
  1208 		else {
       
  1209 			/* Convert UTF-8 to Unicode string */
       
  1210 			p = strchr(p, '\0');
       
  1211 			res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
       
  1212 			if (res == NULL) {
       
  1213 				PyErr_Clear();
       
  1214 				res = PyString_FromStringAndSize(s, (int)(p-s));
       
  1215 			}
       
  1216 		}
       
  1217 #else
       
  1218 		p = strchr(p, '\0');
       
  1219 		res = PyString_FromStringAndSize(s, (int)(p-s));
       
  1220 #endif
       
  1221 	}
       
  1222 	return res;
       
  1223 }
       
  1224 
       
  1225 /* Tkapp_CallProc is the event procedure that is executed in the context of
       
  1226    the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
       
  1227    hold the Python lock. */
       
  1228 
       
  1229 static int
       
  1230 Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
       
  1231 {
       
  1232 	Tcl_Obj *objStore[ARGSZ];
       
  1233 	Tcl_Obj **objv;
       
  1234 	int objc;
       
  1235 	int i;
       
  1236 	ENTER_PYTHON
       
  1237 	objv = Tkapp_CallArgs(e->args, objStore, &objc);
       
  1238 	if (!objv) {
       
  1239 		PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
       
  1240 		*(e->res) = NULL;
       
  1241 	}
       
  1242 	LEAVE_PYTHON
       
  1243 	if (!objv)
       
  1244 		goto done;
       
  1245 	i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
       
  1246 	ENTER_PYTHON
       
  1247 	if (i == TCL_ERROR) {
       
  1248 		*(e->res) = NULL;
       
  1249 		*(e->exc_type) = NULL;
       
  1250 		*(e->exc_tb) = NULL;
       
  1251 		*(e->exc_value) = PyObject_CallFunction(
       
  1252 			Tkinter_TclError, "s",
       
  1253 			Tcl_GetStringResult(e->self->interp));
       
  1254 	}
       
  1255 	else {
       
  1256 		*(e->res) = Tkapp_CallResult(e->self);
       
  1257 	}
       
  1258 	LEAVE_PYTHON
       
  1259   done:
       
  1260 	/* Wake up calling thread. */
       
  1261 	Tcl_MutexLock(&call_mutex);
       
  1262 	Tcl_ConditionNotify(&e->done);
       
  1263 	Tcl_MutexUnlock(&call_mutex);
       
  1264 	return 1;
       
  1265 }
       
  1266 
       
  1267 /* This is the main entry point for calling a Tcl command.
       
  1268    It supports three cases, with regard to threading:
       
  1269    1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
       
  1270       the context of the calling thread.
       
  1271    2. Tcl is threaded, caller of the command is in the interpreter thread:
       
  1272       Execute the command in the calling thread. Since the Tcl lock will
       
  1273       not be used, we can merge that with case 1.
       
  1274    3. Tcl is threaded, caller is in a different thread: Must queue an event to
       
  1275       the interpreter thread. Allocation of Tcl objects needs to occur in the
       
  1276       interpreter thread, so we ship the PyObject* args to the target thread,
       
  1277       and perform processing there. */
       
  1278 
       
  1279 static PyObject *
       
  1280 Tkapp_Call(PyObject *selfptr, PyObject *args)
       
  1281 {
       
  1282 	Tcl_Obj *objStore[ARGSZ];
       
  1283 	Tcl_Obj **objv = NULL;
       
  1284 	int objc, i;
       
  1285 	PyObject *res = NULL;
       
  1286 	TkappObject *self = (TkappObject*)selfptr;
       
  1287 	/* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
       
  1288 	int flags = TCL_EVAL_DIRECT;
       
  1289 
       
  1290 	/* If args is a single tuple, replace with contents of tuple */
       
  1291 	if (1 == PyTuple_Size(args)){
       
  1292 		PyObject* item = PyTuple_GetItem(args, 0);
       
  1293 		if (PyTuple_Check(item))
       
  1294 			args = item;
       
  1295 	}
       
  1296 #ifdef WITH_THREAD
       
  1297 	if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
       
  1298 		/* We cannot call the command directly. Instead, we must
       
  1299 		   marshal the parameters to the interpreter thread. */
       
  1300 		Tkapp_CallEvent *ev;
       
  1301 		PyObject *exc_type, *exc_value, *exc_tb;
       
  1302 		if (!WaitForMainloop(self))
       
  1303 			return NULL;
       
  1304 		ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
       
  1305 		ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
       
  1306 		ev->self = self;
       
  1307 		ev->args = args;
       
  1308 		ev->res = &res;
       
  1309 		ev->exc_type = &exc_type;
       
  1310 		ev->exc_value = &exc_value;
       
  1311 		ev->exc_tb = &exc_tb;
       
  1312 		ev->done = (Tcl_Condition)0;
       
  1313 
       
  1314 		Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &call_mutex);
       
  1315 
       
  1316 		if (res == NULL) {
       
  1317 			if (exc_type)
       
  1318 				PyErr_Restore(exc_type, exc_value, exc_tb);
       
  1319 			else
       
  1320 				PyErr_SetObject(Tkinter_TclError, exc_value);
       
  1321 		}
       
  1322 	}
       
  1323 	else 
       
  1324 #endif
       
  1325 	{
       
  1326 
       
  1327 		objv = Tkapp_CallArgs(args, objStore, &objc);
       
  1328 		if (!objv)
       
  1329 			return NULL;
       
  1330 
       
  1331 		ENTER_TCL
       
  1332 
       
  1333 		i = Tcl_EvalObjv(self->interp, objc, objv, flags);
       
  1334 
       
  1335 		ENTER_OVERLAP
       
  1336 
       
  1337 		if (i == TCL_ERROR)
       
  1338 			Tkinter_Error(selfptr);
       
  1339 		else
       
  1340 			res = Tkapp_CallResult(self);
       
  1341 
       
  1342 		LEAVE_OVERLAP_TCL
       
  1343 
       
  1344 		Tkapp_CallDeallocArgs(objv, objStore, objc);
       
  1345 	}
       
  1346 	return res;
       
  1347 }
       
  1348 
       
  1349 
       
  1350 static PyObject *
       
  1351 Tkapp_GlobalCall(PyObject *self, PyObject *args)
       
  1352 {
       
  1353 	/* Could do the same here as for Tkapp_Call(), but this is not used
       
  1354 	   much, so I can't be bothered.  Unfortunately Tcl doesn't export a
       
  1355 	   way for the user to do what all its Global* variants do (save and
       
  1356 	   reset the scope pointer, call the local version, restore the saved
       
  1357 	   scope pointer). */
       
  1358 
       
  1359 	char *cmd;
       
  1360 	PyObject *res = NULL;
       
  1361 
       
  1362 	CHECK_TCL_APPARTMENT;
       
  1363 
       
  1364 	cmd  = Merge(args);
       
  1365 	if (cmd) {
       
  1366 		int err;
       
  1367 		ENTER_TCL
       
  1368 		err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
       
  1369 		ENTER_OVERLAP
       
  1370 		if (err == TCL_ERROR)
       
  1371 			res = Tkinter_Error(self);
       
  1372 		else
       
  1373 			res = PyString_FromString(Tkapp_Result(self));
       
  1374 		LEAVE_OVERLAP_TCL
       
  1375 		ckfree(cmd);
       
  1376 	}
       
  1377 
       
  1378 	return res;
       
  1379 }
       
  1380 
       
  1381 static PyObject *
       
  1382 Tkapp_Eval(PyObject *self, PyObject *args)
       
  1383 {
       
  1384 	char *script;
       
  1385 	PyObject *res = NULL;
       
  1386 	int err;
       
  1387 
       
  1388 	if (!PyArg_ParseTuple(args, "s:eval", &script))
       
  1389 		return NULL;
       
  1390 
       
  1391 	CHECK_TCL_APPARTMENT;
       
  1392 
       
  1393 	ENTER_TCL
       
  1394 	err = Tcl_Eval(Tkapp_Interp(self), script);
       
  1395 	ENTER_OVERLAP
       
  1396 	if (err == TCL_ERROR)
       
  1397 		res = Tkinter_Error(self);
       
  1398 	else
       
  1399 		res = PyString_FromString(Tkapp_Result(self));
       
  1400 	LEAVE_OVERLAP_TCL
       
  1401 	return res;
       
  1402 }
       
  1403 
       
  1404 static PyObject *
       
  1405 Tkapp_GlobalEval(PyObject *self, PyObject *args)
       
  1406 {
       
  1407 	char *script;
       
  1408 	PyObject *res = NULL;
       
  1409 	int err;
       
  1410 
       
  1411 	if (!PyArg_ParseTuple(args, "s:globaleval", &script))
       
  1412 		return NULL;
       
  1413 
       
  1414 	CHECK_TCL_APPARTMENT;
       
  1415 
       
  1416 	ENTER_TCL
       
  1417 	err = Tcl_GlobalEval(Tkapp_Interp(self), script);
       
  1418 	ENTER_OVERLAP
       
  1419 	if (err == TCL_ERROR)
       
  1420 		res = Tkinter_Error(self);
       
  1421 	else
       
  1422 		res = PyString_FromString(Tkapp_Result(self));
       
  1423 	LEAVE_OVERLAP_TCL
       
  1424 	return res;
       
  1425 }
       
  1426 
       
  1427 static PyObject *
       
  1428 Tkapp_EvalFile(PyObject *self, PyObject *args)
       
  1429 {
       
  1430 	char *fileName;
       
  1431 	PyObject *res = NULL;
       
  1432 	int err;
       
  1433 
       
  1434 	if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
       
  1435 		return NULL;
       
  1436 
       
  1437 	CHECK_TCL_APPARTMENT;
       
  1438 
       
  1439 	ENTER_TCL
       
  1440 	err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
       
  1441 	ENTER_OVERLAP
       
  1442 	if (err == TCL_ERROR)
       
  1443 		res = Tkinter_Error(self);
       
  1444 
       
  1445 	else
       
  1446 		res = PyString_FromString(Tkapp_Result(self));
       
  1447 	LEAVE_OVERLAP_TCL
       
  1448 	return res;
       
  1449 }
       
  1450 
       
  1451 static PyObject *
       
  1452 Tkapp_Record(PyObject *self, PyObject *args)
       
  1453 {
       
  1454 	char *script;
       
  1455 	PyObject *res = NULL;
       
  1456 	int err;
       
  1457 
       
  1458 	if (!PyArg_ParseTuple(args, "s", &script))
       
  1459 		return NULL;
       
  1460 
       
  1461 	CHECK_TCL_APPARTMENT;
       
  1462 
       
  1463 	ENTER_TCL
       
  1464 	err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
       
  1465 	ENTER_OVERLAP
       
  1466 	if (err == TCL_ERROR)
       
  1467 		res = Tkinter_Error(self);
       
  1468 	else
       
  1469 		res = PyString_FromString(Tkapp_Result(self));
       
  1470 	LEAVE_OVERLAP_TCL
       
  1471 	return res;
       
  1472 }
       
  1473 
       
  1474 static PyObject *
       
  1475 Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
       
  1476 {
       
  1477 	char *msg;
       
  1478 
       
  1479 	if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
       
  1480 		return NULL;
       
  1481 	CHECK_TCL_APPARTMENT;
       
  1482 
       
  1483 	ENTER_TCL
       
  1484 	Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
       
  1485 	LEAVE_TCL
       
  1486 
       
  1487 	Py_INCREF(Py_None);
       
  1488 	return Py_None;
       
  1489 }
       
  1490 
       
  1491 
       
  1492 
       
  1493 /** Tcl Variable **/
       
  1494 
       
  1495 TCL_DECLARE_MUTEX(var_mutex)
       
  1496 
       
  1497 typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
       
  1498 typedef struct VarEvent {
       
  1499 	Tcl_Event ev; /* must be first */
       
  1500 	PyObject *self;
       
  1501 	PyObject *args;
       
  1502 	int flags;
       
  1503 	EventFunc func;
       
  1504 	PyObject **res;
       
  1505 	PyObject **exc_type;
       
  1506 	PyObject **exc_val;
       
  1507 	Tcl_Condition cond;
       
  1508 } VarEvent;
       
  1509 
       
  1510 static int
       
  1511 varname_converter(PyObject *in, void *_out)
       
  1512 {
       
  1513 	char **out = (char**)_out;
       
  1514 	if (PyString_Check(in)) {
       
  1515 		*out = PyString_AsString(in);
       
  1516 		return 1;
       
  1517 	}
       
  1518 	if (PyTclObject_Check(in)) {
       
  1519 		*out = PyTclObject_TclString(in);
       
  1520 		return 1;
       
  1521 	}
       
  1522 	/* XXX: Should give diagnostics. */
       
  1523 	return 0;
       
  1524 }	
       
  1525 
       
  1526 static void
       
  1527 var_perform(VarEvent *ev)
       
  1528 {
       
  1529 	*(ev->res) = ev->func(ev->self, ev->args, ev->flags);
       
  1530 	if (!*(ev->res)) {
       
  1531 		PyObject *exc, *val, *tb;
       
  1532 		PyErr_Fetch(&exc, &val, &tb);
       
  1533 		PyErr_NormalizeException(&exc, &val, &tb);
       
  1534 		*(ev->exc_type) = exc;
       
  1535 		*(ev->exc_val) = val;
       
  1536 		Py_DECREF(tb);
       
  1537 	}
       
  1538 		
       
  1539 }
       
  1540 
       
  1541 static int
       
  1542 var_proc(VarEvent* ev, int flags)
       
  1543 {
       
  1544 	ENTER_PYTHON
       
  1545         var_perform(ev);
       
  1546 	Tcl_MutexLock(&var_mutex);
       
  1547 	Tcl_ConditionNotify(&ev->cond);
       
  1548 	Tcl_MutexUnlock(&var_mutex);
       
  1549 	LEAVE_PYTHON
       
  1550 	return 1;
       
  1551 }
       
  1552 
       
  1553 static PyObject*
       
  1554 var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
       
  1555 {
       
  1556 	TkappObject *self = (TkappObject*)selfptr;
       
  1557 #ifdef WITH_THREAD
       
  1558 	if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
       
  1559 		TkappObject *self = (TkappObject*)selfptr;
       
  1560 		VarEvent *ev;
       
  1561 		PyObject *res, *exc_type, *exc_val;
       
  1562 		
       
  1563 		/* The current thread is not the interpreter thread.  Marshal
       
  1564 		   the call to the interpreter thread, then wait for
       
  1565 		   completion. */
       
  1566 		if (!WaitForMainloop(self))
       
  1567 			return NULL;
       
  1568 
       
  1569 		ev = (VarEvent*)ckalloc(sizeof(VarEvent));
       
  1570 
       
  1571 		ev->self = selfptr;
       
  1572 		ev->args = args;
       
  1573 		ev->flags = flags;
       
  1574 		ev->func = func;
       
  1575 		ev->res = &res;
       
  1576 		ev->exc_type = &exc_type;
       
  1577 		ev->exc_val = &exc_val;
       
  1578 		ev->cond = NULL;
       
  1579 		ev->ev.proc = (Tcl_EventProc*)var_proc;
       
  1580 		Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
       
  1581 		if (!res) {
       
  1582 			PyErr_SetObject(exc_type, exc_val);
       
  1583 			Py_DECREF(exc_type);
       
  1584 			Py_DECREF(exc_val);
       
  1585 			return NULL;
       
  1586 		}
       
  1587 		return res;
       
  1588 	}
       
  1589 #endif
       
  1590         /* Tcl is not threaded, or this is the interpreter thread. */
       
  1591 	return func(selfptr, args, flags);
       
  1592 }
       
  1593 
       
  1594 static PyObject *
       
  1595 SetVar(PyObject *self, PyObject *args, int flags)
       
  1596 {
       
  1597 	char *name1, *name2;
       
  1598 	PyObject *newValue;
       
  1599 	PyObject *res = NULL;
       
  1600 	Tcl_Obj *newval, *ok;
       
  1601 
       
  1602 	if (PyArg_ParseTuple(args, "O&O:setvar", 
       
  1603 			     varname_converter, &name1, &newValue)) {
       
  1604 		/* XXX Acquire tcl lock??? */
       
  1605 		newval = AsObj(newValue);
       
  1606 		if (newval == NULL)
       
  1607 			return NULL;
       
  1608 		ENTER_TCL
       
  1609 		ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL, 
       
  1610 				   newval, flags);
       
  1611 		ENTER_OVERLAP
       
  1612 		if (!ok)
       
  1613 			Tkinter_Error(self);
       
  1614 		else {
       
  1615 			res = Py_None;
       
  1616 			Py_INCREF(res);
       
  1617 		}
       
  1618 		LEAVE_OVERLAP_TCL
       
  1619 	}
       
  1620 	else {
       
  1621 		PyErr_Clear();
       
  1622 		if (PyArg_ParseTuple(args, "ssO:setvar",
       
  1623 				     &name1, &name2, &newValue)) {
       
  1624 			/* XXX must hold tcl lock already??? */
       
  1625 			newval = AsObj(newValue);
       
  1626 			ENTER_TCL
       
  1627 			ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
       
  1628 			ENTER_OVERLAP
       
  1629 			if (!ok)
       
  1630 				Tkinter_Error(self);
       
  1631 			else {
       
  1632 				res = Py_None;
       
  1633 				Py_INCREF(res);
       
  1634 			}
       
  1635 			LEAVE_OVERLAP_TCL
       
  1636 		}
       
  1637 		else {
       
  1638 			return NULL;
       
  1639 		}
       
  1640 	}
       
  1641 	return res;
       
  1642 }
       
  1643 
       
  1644 static PyObject *
       
  1645 Tkapp_SetVar(PyObject *self, PyObject *args)
       
  1646 {
       
  1647 	return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
       
  1648 }
       
  1649 
       
  1650 static PyObject *
       
  1651 Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
       
  1652 {
       
  1653 	return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
       
  1654 }
       
  1655 
       
  1656 
       
  1657 
       
  1658 static PyObject *
       
  1659 GetVar(PyObject *self, PyObject *args, int flags)
       
  1660 {
       
  1661 	char *name1, *name2=NULL;
       
  1662 	PyObject *res = NULL;
       
  1663 	Tcl_Obj *tres;
       
  1664 
       
  1665 	if (!PyArg_ParseTuple(args, "O&|s:getvar", 
       
  1666 			      varname_converter, &name1, &name2))
       
  1667 		return NULL;
       
  1668 
       
  1669 	ENTER_TCL
       
  1670 	tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
       
  1671 	ENTER_OVERLAP
       
  1672 	if (tres == NULL) {
       
  1673 		PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
       
  1674 	} else {
       
  1675 		if (((TkappObject*)self)->wantobjects) {
       
  1676 			res = FromObj(self, tres);
       
  1677 		}
       
  1678 		else {
       
  1679 			res = PyString_FromString(Tcl_GetString(tres));
       
  1680 		}
       
  1681 	}
       
  1682 	LEAVE_OVERLAP_TCL
       
  1683 	return res;
       
  1684 }
       
  1685 
       
  1686 static PyObject *
       
  1687 Tkapp_GetVar(PyObject *self, PyObject *args)
       
  1688 {
       
  1689 	return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
       
  1690 }
       
  1691 
       
  1692 static PyObject *
       
  1693 Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
       
  1694 {
       
  1695 	return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
       
  1696 }
       
  1697 
       
  1698 
       
  1699 
       
  1700 static PyObject *
       
  1701 UnsetVar(PyObject *self, PyObject *args, int flags)
       
  1702 {
       
  1703 	char *name1, *name2=NULL;
       
  1704 	int code;
       
  1705 	PyObject *res = NULL;
       
  1706 
       
  1707 	if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
       
  1708 		return NULL;
       
  1709 
       
  1710 	ENTER_TCL
       
  1711 	code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
       
  1712 	ENTER_OVERLAP
       
  1713 	if (code == TCL_ERROR)
       
  1714 		res = Tkinter_Error(self);
       
  1715 	else {
       
  1716 		Py_INCREF(Py_None);
       
  1717 		res = Py_None;
       
  1718 	}
       
  1719 	LEAVE_OVERLAP_TCL
       
  1720 	return res;
       
  1721 }
       
  1722 
       
  1723 static PyObject *
       
  1724 Tkapp_UnsetVar(PyObject *self, PyObject *args)
       
  1725 {
       
  1726 	return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
       
  1727 }
       
  1728 
       
  1729 static PyObject *
       
  1730 Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
       
  1731 {
       
  1732 	return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
       
  1733 }
       
  1734 
       
  1735 
       
  1736 
       
  1737 /** Tcl to Python **/
       
  1738 
       
  1739 static PyObject *
       
  1740 Tkapp_GetInt(PyObject *self, PyObject *args)
       
  1741 {
       
  1742 	char *s;
       
  1743 	int v;
       
  1744 
       
  1745 	if (PyTuple_Size(args) == 1) {
       
  1746 		PyObject* o = PyTuple_GetItem(args, 0);
       
  1747 		if (PyInt_Check(o)) {
       
  1748 			Py_INCREF(o);
       
  1749 			return o;
       
  1750 		}
       
  1751 	}
       
  1752 	if (!PyArg_ParseTuple(args, "s:getint", &s))
       
  1753 		return NULL;
       
  1754 	if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
       
  1755 		return Tkinter_Error(self);
       
  1756 	return Py_BuildValue("i", v);
       
  1757 }
       
  1758 
       
  1759 static PyObject *
       
  1760 Tkapp_GetDouble(PyObject *self, PyObject *args)
       
  1761 {
       
  1762 	char *s;
       
  1763 	double v;
       
  1764 
       
  1765 	if (PyTuple_Size(args) == 1) {
       
  1766 		PyObject *o = PyTuple_GetItem(args, 0);
       
  1767 		if (PyFloat_Check(o)) {
       
  1768 			Py_INCREF(o);
       
  1769 			return o;
       
  1770 		}
       
  1771 	}
       
  1772 	if (!PyArg_ParseTuple(args, "s:getdouble", &s))
       
  1773 		return NULL;
       
  1774 	if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
       
  1775 		return Tkinter_Error(self);
       
  1776 	return Py_BuildValue("d", v);
       
  1777 }
       
  1778 
       
  1779 static PyObject *
       
  1780 Tkapp_GetBoolean(PyObject *self, PyObject *args)
       
  1781 {
       
  1782 	char *s;
       
  1783 	int v;
       
  1784 
       
  1785 	if (PyTuple_Size(args) == 1) {
       
  1786 		PyObject *o = PyTuple_GetItem(args, 0);
       
  1787 		if (PyInt_Check(o)) {
       
  1788 			Py_INCREF(o);
       
  1789 			return o;
       
  1790 		}
       
  1791 	}
       
  1792 	if (!PyArg_ParseTuple(args, "s:getboolean", &s))
       
  1793 		return NULL;
       
  1794 	if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
       
  1795 		return Tkinter_Error(self);
       
  1796 	return PyBool_FromLong(v);
       
  1797 }
       
  1798 
       
  1799 static PyObject *
       
  1800 Tkapp_ExprString(PyObject *self, PyObject *args)
       
  1801 {
       
  1802 	char *s;
       
  1803 	PyObject *res = NULL;
       
  1804 	int retval;
       
  1805 
       
  1806 	if (!PyArg_ParseTuple(args, "s:exprstring", &s))
       
  1807 		return NULL;
       
  1808 	
       
  1809 	CHECK_TCL_APPARTMENT;
       
  1810 
       
  1811 	ENTER_TCL
       
  1812 	retval = Tcl_ExprString(Tkapp_Interp(self), s);
       
  1813 	ENTER_OVERLAP
       
  1814 	if (retval == TCL_ERROR)
       
  1815 		res = Tkinter_Error(self);
       
  1816 	else
       
  1817 		res = Py_BuildValue("s", Tkapp_Result(self));
       
  1818 	LEAVE_OVERLAP_TCL
       
  1819 	return res;
       
  1820 }
       
  1821 
       
  1822 static PyObject *
       
  1823 Tkapp_ExprLong(PyObject *self, PyObject *args)
       
  1824 {
       
  1825 	char *s;
       
  1826 	PyObject *res = NULL;
       
  1827 	int retval;
       
  1828 	long v;
       
  1829 
       
  1830 	if (!PyArg_ParseTuple(args, "s:exprlong", &s))
       
  1831 		return NULL;
       
  1832 
       
  1833 	CHECK_TCL_APPARTMENT;
       
  1834 
       
  1835 	ENTER_TCL
       
  1836 	retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
       
  1837 	ENTER_OVERLAP
       
  1838 	if (retval == TCL_ERROR)
       
  1839 		res = Tkinter_Error(self);
       
  1840 	else
       
  1841 		res = Py_BuildValue("l", v);
       
  1842 	LEAVE_OVERLAP_TCL
       
  1843 	return res;
       
  1844 }
       
  1845 
       
  1846 static PyObject *
       
  1847 Tkapp_ExprDouble(PyObject *self, PyObject *args)
       
  1848 {
       
  1849 	char *s;
       
  1850 	PyObject *res = NULL;
       
  1851 	double v;
       
  1852 	int retval;
       
  1853 
       
  1854 	if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
       
  1855 		return NULL;
       
  1856 	CHECK_TCL_APPARTMENT;
       
  1857 	PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
       
  1858 	ENTER_TCL
       
  1859 	retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
       
  1860 	ENTER_OVERLAP
       
  1861 	PyFPE_END_PROTECT(retval)
       
  1862 	if (retval == TCL_ERROR)
       
  1863 		res = Tkinter_Error(self);
       
  1864 	else
       
  1865 		res = Py_BuildValue("d", v);
       
  1866 	LEAVE_OVERLAP_TCL
       
  1867 	return res;
       
  1868 }
       
  1869 
       
  1870 static PyObject *
       
  1871 Tkapp_ExprBoolean(PyObject *self, PyObject *args)
       
  1872 {
       
  1873 	char *s;
       
  1874 	PyObject *res = NULL;
       
  1875 	int retval;
       
  1876 	int v;
       
  1877 
       
  1878 	if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
       
  1879 		return NULL;
       
  1880 	CHECK_TCL_APPARTMENT;
       
  1881 	ENTER_TCL
       
  1882 	retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
       
  1883 	ENTER_OVERLAP
       
  1884 	if (retval == TCL_ERROR)
       
  1885 		res = Tkinter_Error(self);
       
  1886 	else
       
  1887 		res = Py_BuildValue("i", v);
       
  1888 	LEAVE_OVERLAP_TCL
       
  1889 	return res;
       
  1890 }
       
  1891 
       
  1892 
       
  1893 
       
  1894 static PyObject *
       
  1895 Tkapp_SplitList(PyObject *self, PyObject *args)
       
  1896 {
       
  1897 	char *list;
       
  1898 	int argc;
       
  1899 	char **argv;
       
  1900 	PyObject *v;
       
  1901 	int i;
       
  1902 
       
  1903 	if (PyTuple_Size(args) == 1) {
       
  1904 		v = PyTuple_GetItem(args, 0);
       
  1905 		if (PyTuple_Check(v)) {
       
  1906 			Py_INCREF(v);
       
  1907 			return v;
       
  1908 		}
       
  1909 	}
       
  1910 	if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
       
  1911 		return NULL;
       
  1912 
       
  1913 	if (Tcl_SplitList(Tkapp_Interp(self), list, 
       
  1914 			  &argc, &argv) == TCL_ERROR)  {
       
  1915 		PyMem_Free(list);
       
  1916 		return Tkinter_Error(self);
       
  1917 	}
       
  1918 
       
  1919 	if (!(v = PyTuple_New(argc)))
       
  1920 		goto finally;
       
  1921 
       
  1922 	for (i = 0; i < argc; i++) {
       
  1923 		PyObject *s = PyString_FromString(argv[i]);
       
  1924 		if (!s || PyTuple_SetItem(v, i, s)) {
       
  1925 			Py_DECREF(v);
       
  1926 			v = NULL;
       
  1927 			goto finally;
       
  1928 		}
       
  1929 	}
       
  1930 
       
  1931   finally:
       
  1932 	ckfree(FREECAST argv);
       
  1933 	PyMem_Free(list);
       
  1934 	return v;
       
  1935 }
       
  1936 
       
  1937 static PyObject *
       
  1938 Tkapp_Split(PyObject *self, PyObject *args)
       
  1939 {
       
  1940 	PyObject *v;
       
  1941 	char *list;
       
  1942 
       
  1943 	if (PyTuple_Size(args) == 1) {
       
  1944 		PyObject* o = PyTuple_GetItem(args, 0);
       
  1945 		if (PyTuple_Check(o)) {
       
  1946 			o = SplitObj(o);
       
  1947 			return o;
       
  1948 		}
       
  1949 	}
       
  1950 	if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
       
  1951 		return NULL;
       
  1952 	v = Split(list);
       
  1953 	PyMem_Free(list);
       
  1954 	return v;
       
  1955 }
       
  1956 
       
  1957 static PyObject *
       
  1958 Tkapp_Merge(PyObject *self, PyObject *args)
       
  1959 {
       
  1960 	char *s = Merge(args);
       
  1961 	PyObject *res = NULL;
       
  1962 
       
  1963 	if (s) {
       
  1964 		res = PyString_FromString(s);
       
  1965 		ckfree(s);
       
  1966 	}
       
  1967 
       
  1968 	return res;
       
  1969 }
       
  1970 
       
  1971 
       
  1972 
       
  1973 /** Tcl Command **/
       
  1974 
       
  1975 /* Client data struct */
       
  1976 typedef struct {
       
  1977 	PyObject *self;
       
  1978 	PyObject *func;
       
  1979 } PythonCmd_ClientData;
       
  1980 
       
  1981 static int
       
  1982 PythonCmd_Error(Tcl_Interp *interp)
       
  1983 {
       
  1984 	errorInCmd = 1;
       
  1985 	PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
       
  1986 	LEAVE_PYTHON
       
  1987 	return TCL_ERROR;
       
  1988 }
       
  1989 
       
  1990 /* This is the Tcl command that acts as a wrapper for Python
       
  1991  * function or method.
       
  1992  */
       
  1993 static int
       
  1994 PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
       
  1995 {
       
  1996 	PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
       
  1997 	PyObject *self, *func, *arg, *res;
       
  1998 	int i, rv;
       
  1999 	Tcl_Obj *obj_res;
       
  2000 
       
  2001 	ENTER_PYTHON
       
  2002 
       
  2003 	/* TBD: no error checking here since we know, via the
       
  2004 	 * Tkapp_CreateCommand() that the client data is a two-tuple
       
  2005 	 */
       
  2006 	self = data->self;
       
  2007 	func = data->func;
       
  2008 
       
  2009 	/* Create argument list (argv1, ..., argvN) */
       
  2010 	if (!(arg = PyTuple_New(argc - 1)))
       
  2011 		return PythonCmd_Error(interp);
       
  2012 
       
  2013 	for (i = 0; i < (argc - 1); i++) {
       
  2014 		PyObject *s = PyString_FromString(argv[i + 1]);
       
  2015 		if (!s || PyTuple_SetItem(arg, i, s)) {
       
  2016 			Py_DECREF(arg);
       
  2017 			return PythonCmd_Error(interp);
       
  2018 		}
       
  2019 	}
       
  2020 	res = PyEval_CallObject(func, arg);
       
  2021 	Py_DECREF(arg);
       
  2022 
       
  2023 	if (res == NULL)
       
  2024 		return PythonCmd_Error(interp);
       
  2025 
       
  2026 	obj_res = AsObj(res);
       
  2027 	if (obj_res == NULL) {
       
  2028 		Py_DECREF(res);
       
  2029 		return PythonCmd_Error(interp);
       
  2030 	}
       
  2031 	else {
       
  2032 		Tcl_SetObjResult(Tkapp_Interp(self), obj_res);
       
  2033 		rv = TCL_OK;
       
  2034 	}
       
  2035 
       
  2036 	Py_DECREF(res);
       
  2037 
       
  2038 	LEAVE_PYTHON
       
  2039 
       
  2040 	return rv;
       
  2041 }
       
  2042 
       
  2043 static void
       
  2044 PythonCmdDelete(ClientData clientData)
       
  2045 {
       
  2046 	PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
       
  2047 
       
  2048 	ENTER_PYTHON
       
  2049 	Py_XDECREF(data->self);
       
  2050 	Py_XDECREF(data->func);
       
  2051 	PyMem_DEL(data);
       
  2052 	LEAVE_PYTHON
       
  2053 }
       
  2054 
       
  2055 
       
  2056 
       
  2057 
       
  2058 TCL_DECLARE_MUTEX(command_mutex)
       
  2059 
       
  2060 typedef struct CommandEvent{
       
  2061 	Tcl_Event ev;
       
  2062 	Tcl_Interp* interp;
       
  2063 	char *name;
       
  2064 	int create;
       
  2065 	int *status;
       
  2066 	ClientData *data;
       
  2067 	Tcl_Condition done;
       
  2068 } CommandEvent;
       
  2069 
       
  2070 static int
       
  2071 Tkapp_CommandProc(CommandEvent *ev, int flags)
       
  2072 {
       
  2073 	if (ev->create)
       
  2074 		*ev->status = Tcl_CreateCommand(
       
  2075 			ev->interp, ev->name, PythonCmd,
       
  2076 			ev->data, PythonCmdDelete) == NULL;
       
  2077 	else
       
  2078 		*ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
       
  2079 	Tcl_MutexLock(&command_mutex);
       
  2080 	Tcl_ConditionNotify(&ev->done);
       
  2081 	Tcl_MutexUnlock(&command_mutex);
       
  2082 	return 1;
       
  2083 }
       
  2084 
       
  2085 static PyObject *
       
  2086 Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
       
  2087 {
       
  2088 	TkappObject *self = (TkappObject*)selfptr;
       
  2089 	PythonCmd_ClientData *data;
       
  2090 	char *cmdName;
       
  2091 	PyObject *func;
       
  2092 	int err;
       
  2093 
       
  2094 	if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
       
  2095 		return NULL;
       
  2096 	if (!PyCallable_Check(func)) {
       
  2097 		PyErr_SetString(PyExc_TypeError, "command not callable");
       
  2098 		return NULL;
       
  2099 	}
       
  2100 
       
  2101 #ifdef WITH_THREAD
       
  2102 	if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
       
  2103 	    !WaitForMainloop(self))
       
  2104 		return NULL;
       
  2105 #endif
       
  2106 
       
  2107 	data = PyMem_NEW(PythonCmd_ClientData, 1);
       
  2108 	if (!data)
       
  2109 		return PyErr_NoMemory();
       
  2110 	Py_INCREF(self);
       
  2111 	Py_INCREF(func);
       
  2112 	data->self = selfptr;
       
  2113 	data->func = func;
       
  2114 	
       
  2115 	if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
       
  2116 		CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
       
  2117 		ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
       
  2118 		ev->interp = self->interp;
       
  2119 		ev->create = 1;
       
  2120 		ev->name = cmdName;
       
  2121 		ev->data = (ClientData)data;
       
  2122 		ev->status = &err;
       
  2123 		ev->done = NULL;
       
  2124 		Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
       
  2125 	}
       
  2126 	else {
       
  2127 		ENTER_TCL
       
  2128 		err = Tcl_CreateCommand(
       
  2129 			Tkapp_Interp(self), cmdName, PythonCmd,
       
  2130 			(ClientData)data, PythonCmdDelete) == NULL;
       
  2131 		LEAVE_TCL
       
  2132 	}
       
  2133 	if (err) {
       
  2134 		PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
       
  2135 		PyMem_DEL(data);
       
  2136 		return NULL;
       
  2137 	}
       
  2138 
       
  2139 	Py_INCREF(Py_None);
       
  2140 	return Py_None;
       
  2141 }
       
  2142 
       
  2143 
       
  2144 
       
  2145 static PyObject *
       
  2146 Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
       
  2147 {
       
  2148 	TkappObject *self = (TkappObject*)selfptr;
       
  2149 	char *cmdName;
       
  2150 	int err;
       
  2151 
       
  2152 	if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
       
  2153 		return NULL;
       
  2154 	if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
       
  2155 		CommandEvent *ev;
       
  2156 		ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
       
  2157 		ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
       
  2158 		ev->interp = self->interp;
       
  2159 		ev->create = 0;
       
  2160 		ev->name = cmdName;
       
  2161 		ev->status = &err;
       
  2162 		ev->done = NULL;
       
  2163 		Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, 
       
  2164 				 &command_mutex);
       
  2165 	}
       
  2166 	else {
       
  2167 		ENTER_TCL
       
  2168 		err = Tcl_DeleteCommand(self->interp, cmdName);
       
  2169 		LEAVE_TCL
       
  2170 	}
       
  2171 	if (err == -1) {
       
  2172 		PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
       
  2173 		return NULL;
       
  2174 	}
       
  2175 	Py_INCREF(Py_None);
       
  2176 	return Py_None;
       
  2177 }
       
  2178 
       
  2179 
       
  2180 
       
  2181 #ifdef HAVE_CREATEFILEHANDLER
       
  2182 /** File Handler **/
       
  2183 
       
  2184 typedef struct _fhcdata {
       
  2185 	PyObject *func;
       
  2186 	PyObject *file;
       
  2187 	int id;
       
  2188 	struct _fhcdata *next;
       
  2189 } FileHandler_ClientData;
       
  2190 
       
  2191 static FileHandler_ClientData *HeadFHCD;
       
  2192 
       
  2193 static FileHandler_ClientData *
       
  2194 NewFHCD(PyObject *func, PyObject *file, int id)
       
  2195 {
       
  2196 	FileHandler_ClientData *p;
       
  2197 	p = PyMem_NEW(FileHandler_ClientData, 1);
       
  2198 	if (p != NULL) {
       
  2199 		Py_XINCREF(func);
       
  2200 		Py_XINCREF(file);
       
  2201 		p->func = func;
       
  2202 		p->file = file;
       
  2203 		p->id = id;
       
  2204 		p->next = HeadFHCD;
       
  2205 		HeadFHCD = p;
       
  2206 	}
       
  2207 	return p;
       
  2208 }
       
  2209 
       
  2210 static void
       
  2211 DeleteFHCD(int id)
       
  2212 {
       
  2213 	FileHandler_ClientData *p, **pp;
       
  2214 
       
  2215 	pp = &HeadFHCD;
       
  2216 	while ((p = *pp) != NULL) {
       
  2217 		if (p->id == id) {
       
  2218 			*pp = p->next;
       
  2219 			Py_XDECREF(p->func);
       
  2220 			Py_XDECREF(p->file);
       
  2221 			PyMem_DEL(p);
       
  2222 		}
       
  2223 		else
       
  2224 			pp = &p->next;
       
  2225 	}
       
  2226 }
       
  2227 
       
  2228 static void
       
  2229 FileHandler(ClientData clientData, int mask)
       
  2230 {
       
  2231 	FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
       
  2232 	PyObject *func, *file, *arg, *res;
       
  2233 
       
  2234 	ENTER_PYTHON
       
  2235 	func = data->func;
       
  2236 	file = data->file;
       
  2237 
       
  2238 	arg = Py_BuildValue("(Oi)", file, (long) mask);
       
  2239 	res = PyEval_CallObject(func, arg);
       
  2240 	Py_DECREF(arg);
       
  2241 
       
  2242 	if (res == NULL) {
       
  2243 		errorInCmd = 1;
       
  2244 		PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
       
  2245 	}
       
  2246 	Py_XDECREF(res);
       
  2247 	LEAVE_PYTHON
       
  2248 }
       
  2249 
       
  2250 static PyObject *
       
  2251 Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
       
  2252      /* args is (file, mask, func) */
       
  2253 {
       
  2254 	FileHandler_ClientData *data;
       
  2255 	PyObject *file, *func;
       
  2256 	int mask, tfile;
       
  2257 
       
  2258 	if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
       
  2259 			      &file, &mask, &func))
       
  2260 		return NULL;
       
  2261 
       
  2262 #ifdef WITH_THREAD
       
  2263 	if (!self && !tcl_lock) {
       
  2264 		/* We don't have the Tcl lock since Tcl is threaded. */
       
  2265 		PyErr_SetString(PyExc_RuntimeError,
       
  2266 				"_tkinter.createfilehandler not supported "
       
  2267 				"for threaded Tcl");
       
  2268 		return NULL;
       
  2269 	}
       
  2270 #endif
       
  2271 
       
  2272 	if (self) {
       
  2273 		CHECK_TCL_APPARTMENT;
       
  2274 	}
       
  2275 
       
  2276 	tfile = PyObject_AsFileDescriptor(file);
       
  2277 	if (tfile < 0)
       
  2278 		return NULL;
       
  2279 	if (!PyCallable_Check(func)) {
       
  2280 		PyErr_SetString(PyExc_TypeError, "bad argument list");
       
  2281 		return NULL;
       
  2282 	}
       
  2283 
       
  2284 	data = NewFHCD(func, file, tfile);
       
  2285 	if (data == NULL)
       
  2286 		return NULL;
       
  2287 
       
  2288 	/* Ought to check for null Tcl_File object... */
       
  2289 	ENTER_TCL
       
  2290 	Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
       
  2291 	LEAVE_TCL
       
  2292 	Py_INCREF(Py_None);
       
  2293 	return Py_None;
       
  2294 }
       
  2295 
       
  2296 static PyObject *
       
  2297 Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
       
  2298 {
       
  2299 	PyObject *file;
       
  2300 	int tfile;
       
  2301 
       
  2302 	if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
       
  2303 		return NULL;
       
  2304 
       
  2305 #ifdef WITH_THREAD
       
  2306 	if (!self && !tcl_lock) {
       
  2307 		/* We don't have the Tcl lock since Tcl is threaded. */
       
  2308 		PyErr_SetString(PyExc_RuntimeError,
       
  2309 				"_tkinter.deletefilehandler not supported "
       
  2310 				"for threaded Tcl");
       
  2311 		return NULL;
       
  2312 	}
       
  2313 #endif
       
  2314 
       
  2315 	if (self) {
       
  2316 		CHECK_TCL_APPARTMENT;
       
  2317 	}
       
  2318 
       
  2319 	tfile = PyObject_AsFileDescriptor(file);
       
  2320 	if (tfile < 0)
       
  2321 		return NULL;
       
  2322 
       
  2323 	DeleteFHCD(tfile);
       
  2324 
       
  2325 	/* Ought to check for null Tcl_File object... */
       
  2326 	ENTER_TCL
       
  2327 	Tcl_DeleteFileHandler(tfile);
       
  2328 	LEAVE_TCL
       
  2329 	Py_INCREF(Py_None);
       
  2330 	return Py_None;
       
  2331 }
       
  2332 #endif /* HAVE_CREATEFILEHANDLER */
       
  2333 
       
  2334 
       
  2335 /**** Tktt Object (timer token) ****/
       
  2336 
       
  2337 static PyTypeObject Tktt_Type;
       
  2338 
       
  2339 typedef struct {
       
  2340 	PyObject_HEAD
       
  2341 	Tcl_TimerToken token;
       
  2342 	PyObject *func;
       
  2343 } TkttObject;
       
  2344 
       
  2345 static PyObject *
       
  2346 Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
       
  2347 {
       
  2348 	TkttObject *v = (TkttObject *)self;
       
  2349 	PyObject *func = v->func;
       
  2350 
       
  2351 	if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
       
  2352 		return NULL;
       
  2353 	if (v->token != NULL) {
       
  2354 		Tcl_DeleteTimerHandler(v->token);
       
  2355 		v->token = NULL;
       
  2356 	}
       
  2357 	if (func != NULL) {
       
  2358 		v->func = NULL;
       
  2359 		Py_DECREF(func);
       
  2360 		Py_DECREF(v); /* See Tktt_New() */
       
  2361 	}
       
  2362 	Py_INCREF(Py_None);
       
  2363 	return Py_None;
       
  2364 }
       
  2365 
       
  2366 static PyMethodDef Tktt_methods[] =
       
  2367 {
       
  2368 	{"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
       
  2369 	{NULL, NULL}
       
  2370 };
       
  2371 
       
  2372 static TkttObject *
       
  2373 Tktt_New(PyObject *func)
       
  2374 {
       
  2375 	TkttObject *v;
       
  2376   
       
  2377 	v = PyObject_New(TkttObject, &Tktt_Type);
       
  2378 	if (v == NULL)
       
  2379 		return NULL;
       
  2380 
       
  2381 	Py_INCREF(func);
       
  2382 	v->token = NULL;
       
  2383 	v->func = func;
       
  2384 
       
  2385 	/* Extra reference, deleted when called or when handler is deleted */
       
  2386 	Py_INCREF(v);
       
  2387 	return v;
       
  2388 }
       
  2389 
       
  2390 static void
       
  2391 Tktt_Dealloc(PyObject *self)
       
  2392 {
       
  2393 	TkttObject *v = (TkttObject *)self;
       
  2394 	PyObject *func = v->func;
       
  2395 
       
  2396 	Py_XDECREF(func);
       
  2397 
       
  2398 	PyObject_Del(self);
       
  2399 }
       
  2400 
       
  2401 static PyObject *
       
  2402 Tktt_Repr(PyObject *self)
       
  2403 {
       
  2404 	TkttObject *v = (TkttObject *)self;
       
  2405 	char buf[100];
       
  2406 
       
  2407 	PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
       
  2408 	                v->func == NULL ? ", handler deleted" : "");
       
  2409 	return PyString_FromString(buf);
       
  2410 }
       
  2411 
       
  2412 static PyObject *
       
  2413 Tktt_GetAttr(PyObject *self, char *name)
       
  2414 {
       
  2415 	return Py_FindMethod(Tktt_methods, self, name);
       
  2416 }
       
  2417 
       
  2418 static PyTypeObject Tktt_Type =
       
  2419 {
       
  2420 	PyVarObject_HEAD_INIT(NULL, 0)
       
  2421 	"tktimertoken",			     /*tp_name */
       
  2422 	sizeof(TkttObject),		     /*tp_basicsize */
       
  2423 	0,				     /*tp_itemsize */
       
  2424 	Tktt_Dealloc,			     /*tp_dealloc */
       
  2425 	0,				     /*tp_print */
       
  2426 	Tktt_GetAttr,			     /*tp_getattr */
       
  2427 	0,				     /*tp_setattr */
       
  2428 	0,				     /*tp_compare */
       
  2429 	Tktt_Repr,			     /*tp_repr */
       
  2430 	0,				     /*tp_as_number */
       
  2431 	0,				     /*tp_as_sequence */
       
  2432 	0,				     /*tp_as_mapping */
       
  2433 	0,				     /*tp_hash */
       
  2434 };
       
  2435 
       
  2436 
       
  2437 
       
  2438 /** Timer Handler **/
       
  2439 
       
  2440 static void
       
  2441 TimerHandler(ClientData clientData)
       
  2442 {
       
  2443 	TkttObject *v = (TkttObject *)clientData;
       
  2444 	PyObject *func = v->func;
       
  2445 	PyObject *res;
       
  2446 
       
  2447 	if (func == NULL)
       
  2448 		return;
       
  2449 
       
  2450 	v->func = NULL;
       
  2451 
       
  2452 	ENTER_PYTHON
       
  2453 
       
  2454 	res  = PyEval_CallObject(func, NULL);
       
  2455 	Py_DECREF(func);
       
  2456 	Py_DECREF(v); /* See Tktt_New() */
       
  2457 
       
  2458 	if (res == NULL) {
       
  2459 		errorInCmd = 1;
       
  2460 		PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
       
  2461 	}
       
  2462 	else
       
  2463 		Py_DECREF(res);
       
  2464 
       
  2465 	LEAVE_PYTHON
       
  2466 }
       
  2467 
       
  2468 static PyObject *
       
  2469 Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
       
  2470 {
       
  2471 	int milliseconds;
       
  2472 	PyObject *func;
       
  2473 	TkttObject *v;
       
  2474 
       
  2475 	if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
       
  2476 			      &milliseconds, &func))
       
  2477 		return NULL;
       
  2478 	if (!PyCallable_Check(func)) {
       
  2479 		PyErr_SetString(PyExc_TypeError, "bad argument list");
       
  2480 		return NULL;
       
  2481 	}
       
  2482 
       
  2483 #ifdef WITH_THREAD
       
  2484 	if (!self && !tcl_lock) {
       
  2485 		/* We don't have the Tcl lock since Tcl is threaded. */
       
  2486 		PyErr_SetString(PyExc_RuntimeError,
       
  2487 				"_tkinter.createtimerhandler not supported "
       
  2488 				"for threaded Tcl");
       
  2489 		return NULL;
       
  2490 	}
       
  2491 #endif
       
  2492 
       
  2493 	if (self) {
       
  2494 		CHECK_TCL_APPARTMENT;
       
  2495 	}
       
  2496 
       
  2497 	v = Tktt_New(func);
       
  2498 	if (v) {
       
  2499 		v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
       
  2500 						  (ClientData)v);
       
  2501 	}
       
  2502 
       
  2503 	return (PyObject *) v;
       
  2504 }
       
  2505 
       
  2506 
       
  2507 /** Event Loop **/
       
  2508 
       
  2509 static PyObject *
       
  2510 Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
       
  2511 {
       
  2512 	int threshold = 0;
       
  2513 	TkappObject *self = (TkappObject*)selfptr;
       
  2514 #ifdef WITH_THREAD
       
  2515 	PyThreadState *tstate = PyThreadState_Get();
       
  2516 #endif
       
  2517 
       
  2518 	if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
       
  2519 		return NULL;
       
  2520 
       
  2521 #ifdef WITH_THREAD
       
  2522 	if (!self && !tcl_lock) {
       
  2523 		/* We don't have the Tcl lock since Tcl is threaded. */
       
  2524 		PyErr_SetString(PyExc_RuntimeError,
       
  2525 				"_tkinter.mainloop not supported "
       
  2526 				"for threaded Tcl");
       
  2527 		return NULL;
       
  2528 	}
       
  2529 #endif
       
  2530 
       
  2531 	if (self) {
       
  2532 		CHECK_TCL_APPARTMENT;
       
  2533 		self->dispatching = 1;
       
  2534 	}
       
  2535 
       
  2536 	quitMainLoop = 0;
       
  2537 	while (Tk_GetNumMainWindows() > threshold &&
       
  2538 	       !quitMainLoop &&
       
  2539 	       !errorInCmd)
       
  2540 	{
       
  2541 		int result;
       
  2542 
       
  2543 #ifdef WITH_THREAD
       
  2544 		if (self && self->threaded) {
       
  2545 			/* Allow other Python threads to run. */
       
  2546 			ENTER_TCL
       
  2547 			result = Tcl_DoOneEvent(0);
       
  2548 			LEAVE_TCL
       
  2549 		}
       
  2550 		else {
       
  2551 			Py_BEGIN_ALLOW_THREADS
       
  2552 			if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
       
  2553 			tcl_tstate = tstate;
       
  2554 			result = Tcl_DoOneEvent(TCL_DONT_WAIT);
       
  2555 			tcl_tstate = NULL;
       
  2556 			if(tcl_lock)PyThread_release_lock(tcl_lock);
       
  2557 			if (result == 0)
       
  2558 				Sleep(Tkinter_busywaitinterval);
       
  2559 			Py_END_ALLOW_THREADS
       
  2560 		}
       
  2561 #else
       
  2562 		result = Tcl_DoOneEvent(0);
       
  2563 #endif
       
  2564 
       
  2565 		if (PyErr_CheckSignals() != 0) {
       
  2566 			if (self)
       
  2567 				self->dispatching = 0;
       
  2568 			return NULL;
       
  2569 		}
       
  2570 		if (result < 0)
       
  2571 			break;
       
  2572 	}
       
  2573 	if (self)
       
  2574 		self->dispatching = 0;
       
  2575 	quitMainLoop = 0;
       
  2576 
       
  2577 	if (errorInCmd) {
       
  2578 		errorInCmd = 0;
       
  2579 		PyErr_Restore(excInCmd, valInCmd, trbInCmd);
       
  2580 		excInCmd = valInCmd = trbInCmd = NULL;
       
  2581 		return NULL;
       
  2582 	}
       
  2583 	Py_INCREF(Py_None);
       
  2584 	return Py_None;
       
  2585 }
       
  2586 
       
  2587 static PyObject *
       
  2588 Tkapp_DoOneEvent(PyObject *self, PyObject *args)
       
  2589 {
       
  2590 	int flags = 0;
       
  2591 	int rv;
       
  2592 
       
  2593 	if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
       
  2594 		return NULL;
       
  2595 
       
  2596 	ENTER_TCL
       
  2597 	rv = Tcl_DoOneEvent(flags);
       
  2598 	LEAVE_TCL
       
  2599 	return Py_BuildValue("i", rv);
       
  2600 }
       
  2601 
       
  2602 static PyObject *
       
  2603 Tkapp_Quit(PyObject *self, PyObject *args)
       
  2604 {
       
  2605 
       
  2606 	if (!PyArg_ParseTuple(args, ":quit"))
       
  2607 		return NULL;
       
  2608 
       
  2609 	quitMainLoop = 1;
       
  2610 	Py_INCREF(Py_None);
       
  2611 	return Py_None;
       
  2612 }
       
  2613 
       
  2614 static PyObject *
       
  2615 Tkapp_InterpAddr(PyObject *self, PyObject *args)
       
  2616 {
       
  2617 
       
  2618 	if (!PyArg_ParseTuple(args, ":interpaddr"))
       
  2619 		return NULL;
       
  2620 
       
  2621 	return PyInt_FromLong((long)Tkapp_Interp(self));
       
  2622 }
       
  2623 
       
  2624 static PyObject	*
       
  2625 Tkapp_TkInit(PyObject *self, PyObject *args)
       
  2626 {
       
  2627 	static int has_failed;
       
  2628 	Tcl_Interp *interp = Tkapp_Interp(self);
       
  2629 	Tk_Window main_window;
       
  2630 	const char * _tk_exists = NULL;
       
  2631 	int err;
       
  2632 	main_window = Tk_MainWindow(interp);
       
  2633 
       
  2634 	/* In all current versions of Tk (including 8.4.13), Tk_Init
       
  2635 	   deadlocks on the second call when the first call failed.
       
  2636 	   To avoid the deadlock, we just refuse the second call through
       
  2637 	   a static variable. */
       
  2638 	if (has_failed) {
       
  2639 		PyErr_SetString(Tkinter_TclError, 
       
  2640 				"Calling Tk_Init again after a previous call failed might deadlock");
       
  2641 		return NULL;
       
  2642 	}
       
  2643 	   
       
  2644 	/* We want to guard against calling Tk_Init() multiple times */
       
  2645 	CHECK_TCL_APPARTMENT;
       
  2646 	ENTER_TCL
       
  2647 	err = Tcl_Eval(Tkapp_Interp(self), "info exists	tk_version");
       
  2648 	ENTER_OVERLAP
       
  2649 	if (err == TCL_ERROR) {
       
  2650 		/* This sets an exception, but we cannot return right
       
  2651 		   away because we need to exit the overlap first. */
       
  2652 		Tkinter_Error(self);
       
  2653 	} else {
       
  2654 		_tk_exists = Tkapp_Result(self);
       
  2655 	}
       
  2656 	LEAVE_OVERLAP_TCL
       
  2657 	if (err == TCL_ERROR) {
       
  2658 		return NULL;
       
  2659 	}
       
  2660 	if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0)	{
       
  2661 		if (Tk_Init(interp)	== TCL_ERROR) {
       
  2662 		        PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
       
  2663 			has_failed = 1;
       
  2664 			return NULL;
       
  2665 		}
       
  2666 	}
       
  2667 	Py_INCREF(Py_None);
       
  2668 	return Py_None;
       
  2669 }
       
  2670 
       
  2671 static PyObject *
       
  2672 Tkapp_WantObjects(PyObject *self, PyObject *args)
       
  2673 {
       
  2674 
       
  2675 	int wantobjects = -1;
       
  2676 	if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
       
  2677 		return NULL;
       
  2678 	if (wantobjects == -1)
       
  2679 		return PyBool_FromLong(((TkappObject*)self)->wantobjects);
       
  2680 	((TkappObject*)self)->wantobjects = wantobjects;
       
  2681 
       
  2682 	Py_INCREF(Py_None);
       
  2683 	return Py_None;
       
  2684 }
       
  2685 
       
  2686 static PyObject *
       
  2687 Tkapp_WillDispatch(PyObject *self, PyObject *args)
       
  2688 {
       
  2689 
       
  2690 	((TkappObject*)self)->dispatching = 1;
       
  2691 
       
  2692 	Py_INCREF(Py_None);
       
  2693 	return Py_None;
       
  2694 }
       
  2695 
       
  2696 
       
  2697 /**** Tkapp Method List ****/
       
  2698 
       
  2699 static PyMethodDef Tkapp_methods[] =
       
  2700 {
       
  2701 	{"willdispatch",       Tkapp_WillDispatch, METH_NOARGS},
       
  2702 	{"wantobjects",	       Tkapp_WantObjects, METH_VARARGS},
       
  2703 	{"call", 	       Tkapp_Call, METH_VARARGS},
       
  2704 	{"globalcall", 	       Tkapp_GlobalCall, METH_VARARGS},
       
  2705 	{"eval", 	       Tkapp_Eval, METH_VARARGS},
       
  2706 	{"globaleval", 	       Tkapp_GlobalEval, METH_VARARGS},
       
  2707 	{"evalfile", 	       Tkapp_EvalFile, METH_VARARGS},
       
  2708 	{"record", 	       Tkapp_Record, METH_VARARGS},
       
  2709 	{"adderrorinfo",       Tkapp_AddErrorInfo, METH_VARARGS},
       
  2710 	{"setvar", 	       Tkapp_SetVar, METH_VARARGS},
       
  2711 	{"globalsetvar",       Tkapp_GlobalSetVar, METH_VARARGS},
       
  2712 	{"getvar", 	       Tkapp_GetVar, METH_VARARGS},
       
  2713 	{"globalgetvar",       Tkapp_GlobalGetVar, METH_VARARGS},
       
  2714 	{"unsetvar", 	       Tkapp_UnsetVar, METH_VARARGS},
       
  2715 	{"globalunsetvar",     Tkapp_GlobalUnsetVar, METH_VARARGS},
       
  2716 	{"getint", 	       Tkapp_GetInt, METH_VARARGS},
       
  2717 	{"getdouble", 	       Tkapp_GetDouble, METH_VARARGS},
       
  2718 	{"getboolean", 	       Tkapp_GetBoolean, METH_VARARGS},
       
  2719 	{"exprstring", 	       Tkapp_ExprString, METH_VARARGS},
       
  2720 	{"exprlong", 	       Tkapp_ExprLong, METH_VARARGS},
       
  2721 	{"exprdouble", 	       Tkapp_ExprDouble, METH_VARARGS},
       
  2722 	{"exprboolean",        Tkapp_ExprBoolean, METH_VARARGS},
       
  2723 	{"splitlist", 	       Tkapp_SplitList, METH_VARARGS},
       
  2724 	{"split", 	       Tkapp_Split, METH_VARARGS},
       
  2725 	{"merge", 	       Tkapp_Merge, METH_VARARGS},
       
  2726 	{"createcommand",      Tkapp_CreateCommand, METH_VARARGS},
       
  2727 	{"deletecommand",      Tkapp_DeleteCommand, METH_VARARGS},
       
  2728 #ifdef HAVE_CREATEFILEHANDLER
       
  2729 	{"createfilehandler",  Tkapp_CreateFileHandler, METH_VARARGS},
       
  2730 	{"deletefilehandler",  Tkapp_DeleteFileHandler, METH_VARARGS},
       
  2731 #endif
       
  2732 	{"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
       
  2733 	{"mainloop", 	       Tkapp_MainLoop, METH_VARARGS},
       
  2734 	{"dooneevent", 	       Tkapp_DoOneEvent, METH_VARARGS},
       
  2735 	{"quit", 	       Tkapp_Quit, METH_VARARGS},
       
  2736 	{"interpaddr",         Tkapp_InterpAddr, METH_VARARGS},
       
  2737 	{"loadtk",	       Tkapp_TkInit, METH_NOARGS},
       
  2738 	{NULL, 		       NULL}
       
  2739 };
       
  2740 
       
  2741 
       
  2742 
       
  2743 /**** Tkapp Type Methods ****/
       
  2744 
       
  2745 static void
       
  2746 Tkapp_Dealloc(PyObject *self)
       
  2747 {
       
  2748 	/*CHECK_TCL_APPARTMENT;*/
       
  2749 	ENTER_TCL
       
  2750 	Tcl_DeleteInterp(Tkapp_Interp(self));
       
  2751 	LEAVE_TCL
       
  2752 	PyObject_Del(self);
       
  2753 	DisableEventHook();
       
  2754 }
       
  2755 
       
  2756 static PyObject *
       
  2757 Tkapp_GetAttr(PyObject *self, char *name)
       
  2758 {
       
  2759 	return Py_FindMethod(Tkapp_methods, self, name);
       
  2760 }
       
  2761 
       
  2762 static PyTypeObject Tkapp_Type =
       
  2763 {
       
  2764 	PyVarObject_HEAD_INIT(NULL, 0)
       
  2765 	"tkapp",			     /*tp_name */
       
  2766 	sizeof(TkappObject),		     /*tp_basicsize */
       
  2767 	0,				     /*tp_itemsize */
       
  2768 	Tkapp_Dealloc,			     /*tp_dealloc */
       
  2769 	0,				     /*tp_print */
       
  2770 	Tkapp_GetAttr,			     /*tp_getattr */
       
  2771 	0,				     /*tp_setattr */
       
  2772 	0,				     /*tp_compare */
       
  2773 	0,				     /*tp_repr */
       
  2774 	0,				     /*tp_as_number */
       
  2775 	0,				     /*tp_as_sequence */
       
  2776 	0,				     /*tp_as_mapping */
       
  2777 	0,				     /*tp_hash */
       
  2778 };
       
  2779 
       
  2780 
       
  2781 
       
  2782 /**** Tkinter Module ****/
       
  2783 
       
  2784 typedef struct {
       
  2785 	PyObject* tuple;
       
  2786 	int size; /* current size */
       
  2787 	int maxsize; /* allocated size */
       
  2788 } FlattenContext;
       
  2789 
       
  2790 static int
       
  2791 _bump(FlattenContext* context, int size)
       
  2792 {
       
  2793 	/* expand tuple to hold (at least) size new items.
       
  2794 	   return true if successful, false if an exception was raised */
       
  2795 
       
  2796 	int maxsize = context->maxsize * 2;
       
  2797 
       
  2798 	if (maxsize < context->size + size)
       
  2799 		maxsize = context->size + size;
       
  2800 
       
  2801 	context->maxsize = maxsize;
       
  2802 
       
  2803 	return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
       
  2804 }
       
  2805 
       
  2806 static int
       
  2807 _flatten1(FlattenContext* context, PyObject* item, int depth)
       
  2808 {
       
  2809 	/* add tuple or list to argument tuple (recursively) */
       
  2810 
       
  2811 	int i, size;
       
  2812 
       
  2813 	if (depth > 1000) {
       
  2814 		PyErr_SetString(PyExc_ValueError,
       
  2815 				"nesting too deep in _flatten");
       
  2816 		return 0;
       
  2817 	} else if (PyList_Check(item)) {
       
  2818 		size = PyList_GET_SIZE(item);
       
  2819 		/* preallocate (assume no nesting) */
       
  2820 		if (context->size + size > context->maxsize &&
       
  2821 		    !_bump(context, size))
       
  2822 			return 0;
       
  2823 		/* copy items to output tuple */
       
  2824 		for (i = 0; i < size; i++) {
       
  2825 			PyObject *o = PyList_GET_ITEM(item, i);
       
  2826 			if (PyList_Check(o) || PyTuple_Check(o)) {
       
  2827 				if (!_flatten1(context, o, depth + 1))
       
  2828 					return 0;
       
  2829 			} else if (o != Py_None) {
       
  2830 				if (context->size + 1 > context->maxsize &&
       
  2831 				    !_bump(context, 1))
       
  2832 					return 0;
       
  2833 				Py_INCREF(o);
       
  2834 				PyTuple_SET_ITEM(context->tuple,
       
  2835 						 context->size++, o);
       
  2836 			}
       
  2837 		}
       
  2838 	} else if (PyTuple_Check(item)) {
       
  2839 		/* same, for tuples */
       
  2840 		size = PyTuple_GET_SIZE(item);
       
  2841 		if (context->size + size > context->maxsize &&
       
  2842 		    !_bump(context, size))
       
  2843 			return 0;
       
  2844 		for (i = 0; i < size; i++) {
       
  2845 			PyObject *o = PyTuple_GET_ITEM(item, i);
       
  2846 			if (PyList_Check(o) || PyTuple_Check(o)) {
       
  2847 				if (!_flatten1(context, o, depth + 1))
       
  2848 					return 0;
       
  2849 			} else if (o != Py_None) {
       
  2850 				if (context->size + 1 > context->maxsize &&
       
  2851 				    !_bump(context, 1))
       
  2852 					return 0;
       
  2853 				Py_INCREF(o);
       
  2854 				PyTuple_SET_ITEM(context->tuple,
       
  2855 						 context->size++, o);
       
  2856 			}
       
  2857 		}
       
  2858 	} else {
       
  2859 		PyErr_SetString(PyExc_TypeError, "argument must be sequence");
       
  2860 		return 0;
       
  2861 	}
       
  2862 	return 1;
       
  2863 }
       
  2864 
       
  2865 static PyObject *
       
  2866 Tkinter_Flatten(PyObject* self, PyObject* args)
       
  2867 {
       
  2868 	FlattenContext context;
       
  2869 	PyObject* item;
       
  2870 
       
  2871 	if (!PyArg_ParseTuple(args, "O:_flatten", &item))
       
  2872 		return NULL;
       
  2873 
       
  2874 	context.maxsize = PySequence_Size(item);
       
  2875 	if (context.maxsize <= 0)
       
  2876 		return PyTuple_New(0);
       
  2877 	
       
  2878 	context.tuple = PyTuple_New(context.maxsize);
       
  2879 	if (!context.tuple)
       
  2880 		return NULL;
       
  2881 	
       
  2882 	context.size = 0;
       
  2883 
       
  2884 	if (!_flatten1(&context, item,0))
       
  2885 		return NULL;
       
  2886 
       
  2887 	if (_PyTuple_Resize(&context.tuple, context.size))
       
  2888 		return NULL;
       
  2889 
       
  2890 	return context.tuple;
       
  2891 }
       
  2892 
       
  2893 static PyObject *
       
  2894 Tkinter_Create(PyObject *self, PyObject *args)
       
  2895 {
       
  2896 	char *screenName = NULL;
       
  2897 	char *baseName = NULL;
       
  2898 	char *className = NULL;
       
  2899 	int interactive = 0;
       
  2900 	int wantobjects = 0;
       
  2901 	int wantTk = 1;	/* If false, then Tk_Init() doesn't get	called */
       
  2902 	int sync = 0; /* pass -sync to wish */
       
  2903 	char *use = NULL; /* pass -use to wish */
       
  2904 
       
  2905 	baseName = strrchr(Py_GetProgramName(), '/');
       
  2906 	if (baseName != NULL)
       
  2907 		baseName++;
       
  2908 	else
       
  2909 		baseName = Py_GetProgramName();
       
  2910 	className = "Tk";
       
  2911   
       
  2912 	if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
       
  2913 			      &screenName, &baseName, &className,
       
  2914 			      &interactive, &wantobjects, &wantTk,
       
  2915 			      &sync, &use))
       
  2916 		return NULL;
       
  2917 
       
  2918 	return (PyObject *) Tkapp_New(screenName, baseName, className, 
       
  2919 				      interactive, wantobjects,	wantTk,
       
  2920 				      sync, use);
       
  2921 }
       
  2922 
       
  2923 static PyObject *
       
  2924 Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
       
  2925 {
       
  2926 	int new_val;
       
  2927 	if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
       
  2928 		return NULL;
       
  2929 	if (new_val < 0) {
       
  2930 		PyErr_SetString(PyExc_ValueError,
       
  2931 				"busywaitinterval must be >= 0");
       
  2932 		return NULL;
       
  2933 	}
       
  2934 	Tkinter_busywaitinterval = new_val;
       
  2935 	Py_INCREF(Py_None);
       
  2936 	return Py_None;
       
  2937 }
       
  2938 
       
  2939 static char setbusywaitinterval_doc[] =
       
  2940 "setbusywaitinterval(n) -> None\n\
       
  2941 \n\
       
  2942 Set the busy-wait interval in milliseconds between successive\n\
       
  2943 calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
       
  2944 It should be set to a divisor of the maximum time between\n\
       
  2945 frames in an animation.";
       
  2946 
       
  2947 static PyObject *
       
  2948 Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
       
  2949 {
       
  2950         return PyInt_FromLong(Tkinter_busywaitinterval);
       
  2951 }
       
  2952 
       
  2953 static char getbusywaitinterval_doc[] =
       
  2954 "getbusywaitinterval() -> int\n\
       
  2955 \n\
       
  2956 Return the current busy-wait interval between successive\n\
       
  2957 calls to Tcl_DoOneEvent in a threaded Python interpreter.";
       
  2958 
       
  2959 static PyMethodDef moduleMethods[] =
       
  2960 {
       
  2961 	{"_flatten",           Tkinter_Flatten, METH_VARARGS},
       
  2962 	{"create",             Tkinter_Create, METH_VARARGS},
       
  2963 #ifdef HAVE_CREATEFILEHANDLER
       
  2964 	{"createfilehandler",  Tkapp_CreateFileHandler, METH_VARARGS},
       
  2965 	{"deletefilehandler",  Tkapp_DeleteFileHandler, METH_VARARGS},
       
  2966 #endif
       
  2967 	{"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
       
  2968 	{"mainloop",           Tkapp_MainLoop, METH_VARARGS},
       
  2969 	{"dooneevent",         Tkapp_DoOneEvent, METH_VARARGS},
       
  2970 	{"quit",               Tkapp_Quit, METH_VARARGS},
       
  2971 	{"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
       
  2972 	                       setbusywaitinterval_doc},
       
  2973 	{"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
       
  2974 	                       METH_NOARGS, getbusywaitinterval_doc},
       
  2975 	{NULL,                 NULL}
       
  2976 };
       
  2977 
       
  2978 #ifdef WAIT_FOR_STDIN
       
  2979 
       
  2980 static int stdin_ready = 0;
       
  2981 
       
  2982 #ifndef MS_WINDOWS
       
  2983 static void
       
  2984 MyFileProc(void *clientData, int mask)
       
  2985 {
       
  2986 	stdin_ready = 1;
       
  2987 }
       
  2988 #endif
       
  2989 
       
  2990 #ifdef WITH_THREAD
       
  2991 static PyThreadState *event_tstate = NULL;
       
  2992 #endif
       
  2993 
       
  2994 static int
       
  2995 EventHook(void)
       
  2996 {
       
  2997 #ifndef MS_WINDOWS
       
  2998 	int tfile;
       
  2999 #endif
       
  3000 #ifdef WITH_THREAD
       
  3001 	PyEval_RestoreThread(event_tstate);
       
  3002 #endif
       
  3003 	stdin_ready = 0;
       
  3004 	errorInCmd = 0;
       
  3005 #ifndef MS_WINDOWS
       
  3006 	tfile = fileno(stdin);
       
  3007 	Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
       
  3008 #endif
       
  3009 	while (!errorInCmd && !stdin_ready) {
       
  3010 		int result;
       
  3011 #ifdef MS_WINDOWS
       
  3012 		if (_kbhit()) {
       
  3013 			stdin_ready = 1;
       
  3014 			break;
       
  3015 		}
       
  3016 #endif
       
  3017 #if defined(WITH_THREAD) || defined(MS_WINDOWS)
       
  3018 		Py_BEGIN_ALLOW_THREADS
       
  3019 		if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
       
  3020 		tcl_tstate = event_tstate;
       
  3021 
       
  3022 		result = Tcl_DoOneEvent(TCL_DONT_WAIT);
       
  3023 
       
  3024 		tcl_tstate = NULL;
       
  3025 		if(tcl_lock)PyThread_release_lock(tcl_lock);
       
  3026 		if (result == 0)
       
  3027 			Sleep(Tkinter_busywaitinterval);
       
  3028 		Py_END_ALLOW_THREADS
       
  3029 #else
       
  3030 		result = Tcl_DoOneEvent(0);
       
  3031 #endif
       
  3032 
       
  3033 		if (result < 0)
       
  3034 			break;
       
  3035 	}
       
  3036 #ifndef MS_WINDOWS
       
  3037 	Tcl_DeleteFileHandler(tfile);
       
  3038 #endif
       
  3039 	if (errorInCmd) {
       
  3040 		errorInCmd = 0;
       
  3041 		PyErr_Restore(excInCmd, valInCmd, trbInCmd);
       
  3042 		excInCmd = valInCmd = trbInCmd = NULL;
       
  3043 		PyErr_Print();
       
  3044 	}
       
  3045 #ifdef WITH_THREAD
       
  3046 	PyEval_SaveThread();
       
  3047 #endif
       
  3048 	return 0;
       
  3049 }
       
  3050 
       
  3051 #endif
       
  3052 
       
  3053 static void
       
  3054 EnableEventHook(void)
       
  3055 {
       
  3056 #ifdef WAIT_FOR_STDIN
       
  3057 	if (PyOS_InputHook == NULL) {
       
  3058 #ifdef WITH_THREAD
       
  3059 		event_tstate = PyThreadState_Get();
       
  3060 #endif
       
  3061 		PyOS_InputHook = EventHook;
       
  3062 	}
       
  3063 #endif
       
  3064 }
       
  3065 
       
  3066 static void
       
  3067 DisableEventHook(void)
       
  3068 {
       
  3069 #ifdef WAIT_FOR_STDIN
       
  3070 	if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
       
  3071 		PyOS_InputHook = NULL;
       
  3072 	}
       
  3073 #endif
       
  3074 }
       
  3075 
       
  3076 
       
  3077 /* all errors will be checked in one fell swoop in init_tkinter() */
       
  3078 static void
       
  3079 ins_long(PyObject *d, char *name, long val)
       
  3080 {
       
  3081 	PyObject *v = PyInt_FromLong(val);
       
  3082 	if (v) {
       
  3083 		PyDict_SetItemString(d, name, v);
       
  3084 		Py_DECREF(v);
       
  3085 	}
       
  3086 }
       
  3087 static void
       
  3088 ins_string(PyObject *d, char *name, char *val)
       
  3089 {
       
  3090 	PyObject *v = PyString_FromString(val);
       
  3091 	if (v) {
       
  3092 		PyDict_SetItemString(d, name, v);
       
  3093 		Py_DECREF(v);
       
  3094 	}
       
  3095 }
       
  3096 
       
  3097 
       
  3098 PyMODINIT_FUNC
       
  3099 init_tkinter(void)
       
  3100 {
       
  3101 	PyObject *m, *d;
       
  3102 
       
  3103 	Py_TYPE(&Tkapp_Type) = &PyType_Type;
       
  3104 
       
  3105 #ifdef WITH_THREAD
       
  3106 	tcl_lock = PyThread_allocate_lock();
       
  3107 #endif
       
  3108 
       
  3109 	m = Py_InitModule("_tkinter", moduleMethods);
       
  3110 	if (m == NULL)
       
  3111 		return;
       
  3112 
       
  3113 	d = PyModule_GetDict(m);
       
  3114 	Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
       
  3115 	PyDict_SetItemString(d, "TclError", Tkinter_TclError);
       
  3116 
       
  3117 	ins_long(d, "READABLE", TCL_READABLE);
       
  3118 	ins_long(d, "WRITABLE", TCL_WRITABLE);
       
  3119 	ins_long(d, "EXCEPTION", TCL_EXCEPTION);
       
  3120 	ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
       
  3121 	ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
       
  3122 	ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
       
  3123 	ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
       
  3124 	ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
       
  3125 	ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
       
  3126 	ins_string(d, "TK_VERSION", TK_VERSION);
       
  3127 	ins_string(d, "TCL_VERSION", TCL_VERSION);
       
  3128 
       
  3129 	PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
       
  3130 
       
  3131 	Py_TYPE(&Tktt_Type) = &PyType_Type;
       
  3132 	PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
       
  3133 
       
  3134 	Py_TYPE(&PyTclObject_Type) = &PyType_Type;
       
  3135 	PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
       
  3136 
       
  3137 #ifdef TK_AQUA
       
  3138 	/* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
       
  3139 	 * start waking up.  Note that Tcl_FindExecutable will do this, this
       
  3140 	 * code must be above it! The original warning from
       
  3141 	 * tkMacOSXAppInit.c is copied below.
       
  3142 	 *
       
  3143 	 * NB - You have to swap in the Tk Notifier BEFORE you start up the
       
  3144 	 * Tcl interpreter for now.  It probably should work to do this
       
  3145 	 * in the other order, but for now it doesn't seem to.
       
  3146 	 *
       
  3147 	 */
       
  3148 	Tk_MacOSXSetupTkNotifier();
       
  3149 #endif
       
  3150 
       
  3151 
       
  3152 	/* This helps the dynamic loader; in Unicode aware Tcl versions
       
  3153 	   it also helps Tcl find its encodings. */
       
  3154 	Tcl_FindExecutable(Py_GetProgramName());
       
  3155 
       
  3156 	if (PyErr_Occurred())
       
  3157 		return;
       
  3158 
       
  3159 #if 0
       
  3160 	/* This was not a good idea; through <Destroy> bindings,
       
  3161 	   Tcl_Finalize() may invoke Python code but at that point the
       
  3162 	   interpreter and thread state have already been destroyed! */
       
  3163 	Py_AtExit(Tcl_Finalize);
       
  3164 #endif
       
  3165 
       
  3166 }