blob: 4e36daccd3d4930e657e93ee0c60f6651e574888 [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
Guido van Rossum845547d1996-06-26 18:26:04 +00003
4 All Rights Reserved
5
Guido van Rossum845547d1996-06-26 18:26:04 +00006******************************************************************/
7
8/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +00009
Guido van Rossum7ffa7611996-08-13 21:10:16 +000010/* TCL/TK VERSION INFO:
11
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000012 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
Guido van Rossuma80649b2000-03-28 20:07:05 +000014 libraries.)
15*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000016
Guido van Rossuma80649b2000-03-28 20:07:05 +000017/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000018
Guido van Rossum212643f1998-04-29 16:22:14 +000019 - 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
Guido van Rossum7ffa7611996-08-13 21:10:16 +000022*/
23
Guido van Rossum35d43371997-08-02 00:09:09 +000024
Guido van Rossum9722ad81995-09-22 23:49:28 +000025#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000026#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000027
Guido van Rossum00d93061998-05-28 23:06:38 +000028#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000029#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000030#endif
31
Guido van Rossum2a5119b1998-05-29 01:28:40 +000032#ifdef MS_WINDOWS
33#include <windows.h>
34#endif
35
Martin v. Löwis39195712003-01-04 00:33:13 +000036/* Allow using this code in Python 2.[12] */
37#ifndef PyDoc_STRVAR
Martin v. Löwiscd9a8b62003-01-21 21:52:57 +000038#define PyDoc_STRVAR(name,str) static char name[] = str
Martin v. Löwis39195712003-01-04 00:33:13 +000039#endif
40
41#ifndef PyMODINIT_FUNC
Martin v. Löwis3a57d9d2003-01-04 08:54:59 +000042#define PyMODINIT_FUNC void
Martin v. Löwis39195712003-01-04 00:33:13 +000043#endif
44
Martin v. Löwis52ae6f62003-03-30 08:26:04 +000045#ifndef PyBool_Check
46#define PyBool_Check(o) 0
Christian Heimes217cfd12007-12-02 14:31:20 +000047#define PyBool_FromLong PyLong_FromLong
Martin v. Löwis52ae6f62003-03-30 08:26:04 +000048#endif
49
Martin v. Löwis71e25a02002-10-01 18:08:06 +000050/* 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
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000057/* 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
Jack Jansencb852442001-12-09 23:15:56 +000062#ifdef TK_FRAMEWORK
63#include <Tcl/tcl.h>
64#include <Tk/tk.h>
65#else
Guido van Rossum18468821994-06-20 07:49:28 +000066#include <tcl.h>
67#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000068#endif
Guido van Rossum18468821994-06-20 07:49:28 +000069
Jason Tishlerbbe89612002-12-31 20:30:46 +000070/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
Martin v. Löwis5b177f12002-12-30 18:14:15 +000071#ifndef CONST84_RETURN
72#define CONST84_RETURN
Jason Tishlerbbe89612002-12-31 20:30:46 +000073#undef CONST
Martin v. Löwis5b177f12002-12-30 18:14:15 +000074#define CONST
75#endif
76
Guido van Rossum3e819a71997-08-01 19:29:02 +000077#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
78
Martin v. Löwis6bfa2e62002-10-01 17:48:31 +000079#if TKMAJORMINOR < 8002
80#error "Tk older than 8.2 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000081#endif
82
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000083/* 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
Guido van Rossum82c0dfa2007-11-21 20:09:18 +000086 either UTF-16 or UCS-4.
87 Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for
Martin v. Löwis6f29ff32003-04-16 20:34:55 +000088 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)
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000092#error "unsupported Tcl configuration"
93#endif
94
Jack Janseneddc1442003-11-20 01:44:59 +000095#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
Guido van Rossum0d2390c1997-08-14 19:57:07 +000096#define HAVE_CREATEFILEHANDLER
97#endif
98
Guido van Rossum00d93061998-05-28 23:06:38 +000099#ifdef HAVE_CREATEFILEHANDLER
100
Neal Norwitzd948a432006-01-08 01:08:55 +0000101/* 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
Guido van Rossum00d93061998-05-28 23:06:38 +0000111/* 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
Guido van Rossum7bf15641998-05-22 18:28:17 +0000116#ifdef MS_WINDOWS
117#define FHANDLETYPE TCL_WIN_SOCKET
118#else
119#define FHANDLETYPE TCL_UNIX_FD
120#endif
121
Guido van Rossum00d93061998-05-28 23:06:38 +0000122/* 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
Guido van Rossum7bf15641998-05-22 18:28:17 +0000126#define WAIT_FOR_STDIN
127#endif
128
Guido van Rossum00d93061998-05-28 23:06:38 +0000129#endif /* HAVE_CREATEFILEHANDLER */
130
Guido van Rossumad4db171998-06-13 13:56:28 +0000131#ifdef MS_WINDOWS
132#include <conio.h>
133#define WAIT_FOR_STDIN
134#endif
135
Guido van Rossum00d93061998-05-28 23:06:38 +0000136#ifdef WITH_THREAD
137
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000138/* The threading situation is complicated. Tcl is not thread-safe, except
139 when configured with --enable-threads.
Guido van Rossum00d93061998-05-28 23:06:38 +0000140 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
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000152 interpreter lock; inside the brackets, the Python interpreter lock has been
Guido van Rossum00d93061998-05-28 23:06:38 +0000153 released and the lock for Tcl has been acquired.
154
Guido van Rossum5e977831998-06-15 14:03:52 +0000155 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
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000162 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000163 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
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000165 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000166 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
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000169 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000170
171 These locks expand to several statements and brackets; they should not be
172 used in branches of if statements and the like.
173
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000174 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
Guido van Rossum00d93061998-05-28 23:06:38 +0000187*/
188
Guido van Rossum65d5b571998-12-21 19:32:43 +0000189static PyThread_type_lock tcl_lock = 0;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000190
191#ifdef TCL_THREADS
192static Tcl_ThreadDataKey state_key;
193typedef PyThreadState *ThreadSpecificData;
194#define tcl_tstate (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*)))
195#else
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000196static PyThreadState *tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000197#endif
Guido van Rossum00d93061998-05-28 23:06:38 +0000198
199#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000200 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000201 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000202
203#define LEAVE_TCL \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000204 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000205
Guido van Rossum62320c91998-06-15 04:36:09 +0000206#define ENTER_OVERLAP \
207 Py_END_ALLOW_THREADS
208
209#define LEAVE_OVERLAP_TCL \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000210 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000211
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000212#define ENTER_PYTHON \
213 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000214 if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000215
216#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000217 { PyThreadState *tstate = PyEval_SaveThread(); \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000218 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 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000226
227#else
228
229#define ENTER_TCL
230#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000231#define ENTER_OVERLAP
232#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000233#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000234#define LEAVE_PYTHON
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000235#define CHECK_TCL_APPARTMENT
Guido van Rossum00d93061998-05-28 23:06:38 +0000236
237#endif
238
Guido van Rossum97867b21996-08-08 19:09:53 +0000239#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000240#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000241#endif
242
Guido van Rossum18468821994-06-20 07:49:28 +0000243/**** Tkapp Object Declaration ****/
244
Jeremy Hylton938ace62002-07-17 16:30:39 +0000245static PyTypeObject Tkapp_Type;
Guido van Rossum18468821994-06-20 07:49:28 +0000246
Guido van Rossum00d93061998-05-28 23:06:38 +0000247typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000248 PyObject_HEAD
249 Tcl_Interp *interp;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000250 int wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000251 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.
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000255 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;
Guido van Rossum00d93061998-05-28 23:06:38 +0000263} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000264
Christian Heimes90aa7642007-12-19 02:45:37 +0000265#define Tkapp_Check(v) (Py_TYPE(v) == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000266#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000267#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000268
Guido van Rossum35d43371997-08-02 00:09:09 +0000269#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Christian Heimes90aa7642007-12-19 02:45:37 +0000270(void *) v, Py_REFCNT(v)))
Guido van Rossum18468821994-06-20 07:49:28 +0000271
Barry Warsawfa701a81997-01-16 00:15:11 +0000272
273
Guido van Rossum18468821994-06-20 07:49:28 +0000274/**** Error Handling ****/
275
276static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000277static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000278static int errorInCmd = 0;
279static PyObject *excInCmd;
280static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000282
Barry Warsawfa701a81997-01-16 00:15:11 +0000283
284
Guido van Rossum18468821994-06-20 07:49:28 +0000285static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000286Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000287{
Barry Warsawfa701a81997-01-16 00:15:11 +0000288 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
289 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000290}
291
Barry Warsawfa701a81997-01-16 00:15:11 +0000292
Barry Warsawfa701a81997-01-16 00:15:11 +0000293
Guido van Rossum18468821994-06-20 07:49:28 +0000294/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000295
Martin v. Löwis28e9ce92003-05-09 08:19:48 +0000296static int Tkinter_busywaitinterval = 20;
297
Guido van Rossum00d93061998-05-28 23:06:38 +0000298#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000299#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000300
Guido van Rossum00d93061998-05-28 23:06:38 +0000301/* Millisecond sleep() for Unix platforms. */
302
303static void
Fred Drake509d79a2000-07-08 04:04:38 +0000304Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000305{
306 /* XXX Too bad if you don't have select(). */
307 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000308 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}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000312#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000313
Martin v. Löwis5b26abb2002-12-28 09:23:09 +0000314/* Wait up to 1s for the mainloop to come up. */
315
316static int
317WaitForMainloop(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}
Martin v. Löwisa9656492003-03-30 08:44:58 +0000332#endif /* WITH_THREAD */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000333
Guido van Rossum00d93061998-05-28 23:06:38 +0000334
Guido van Rossum18468821994-06-20 07:49:28 +0000335static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000336AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000337{
Christian Heimes72b710a2008-05-26 13:28:38 +0000338 if (PyBytes_Check(value))
339 return PyBytes_AsString(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000340 else if (PyUnicode_Check(value)) {
341 PyObject *v = PyUnicode_AsUTF8String(value);
342 if (v == NULL)
343 return NULL;
344 if (PyList_Append(tmp, v) != 0) {
345 Py_DECREF(v);
346 return NULL;
347 }
348 Py_DECREF(v);
Christian Heimes72b710a2008-05-26 13:28:38 +0000349 return PyBytes_AsString(v);
Guido van Rossum2834b972000-10-06 16:58:26 +0000350 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000351 else {
352 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000353 if (v == NULL)
354 return NULL;
355 if (PyList_Append(tmp, v) != 0) {
356 Py_DECREF(v);
357 return NULL;
358 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000359 Py_DECREF(v);
Christian Heimes72b710a2008-05-26 13:28:38 +0000360 return PyBytes_AsString(v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000361 }
Guido van Rossum18468821994-06-20 07:49:28 +0000362}
363
Barry Warsawfa701a81997-01-16 00:15:11 +0000364
365
Guido van Rossum18468821994-06-20 07:49:28 +0000366#define ARGSZ 64
367
368static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000369Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000370{
Barry Warsawfa701a81997-01-16 00:15:11 +0000371 PyObject *tmp = NULL;
372 char *argvStore[ARGSZ];
373 char **argv = NULL;
374 int fvStore[ARGSZ];
375 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000376 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000377 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000378
Barry Warsawfa701a81997-01-16 00:15:11 +0000379 if (!(tmp = PyList_New(0)))
380 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000381
Barry Warsawfa701a81997-01-16 00:15:11 +0000382 argv = argvStore;
383 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000384
Barry Warsawfa701a81997-01-16 00:15:11 +0000385 if (args == NULL)
386 argc = 0;
387
388 else if (!PyTuple_Check(args)) {
389 argc = 1;
390 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000391 if (!(argv[0] = AsString(args, tmp)))
392 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000393 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000394 else {
395 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000396
Barry Warsawfa701a81997-01-16 00:15:11 +0000397 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000398 argv = (char **)ckalloc(argc * sizeof(char *));
399 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 if (argv == NULL || fv == NULL) {
401 PyErr_NoMemory();
402 goto finally;
403 }
404 }
405
406 for (i = 0; i < argc; i++) {
407 PyObject *v = PyTuple_GetItem(args, i);
408 if (PyTuple_Check(v)) {
409 fv[i] = 1;
410 if (!(argv[i] = Merge(v)))
411 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000412 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000413 }
414 else if (v == Py_None) {
415 argc = i;
416 break;
417 }
418 else {
419 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000420 if (!(argv[i] = AsString(v, tmp)))
421 goto finally;
422 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000423 }
424 }
Guido van Rossum18468821994-06-20 07:49:28 +0000425 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000426 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000427 if (res == NULL)
428 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000429
Barry Warsawfa701a81997-01-16 00:15:11 +0000430 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000431 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000432 if (fv[i]) {
433 ckfree(argv[i]);
434 }
435 if (argv != argvStore)
436 ckfree(FREECAST argv);
437 if (fv != fvStore)
438 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000439
Barry Warsawfa701a81997-01-16 00:15:11 +0000440 Py_DECREF(tmp);
441 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000442}
443
Barry Warsawfa701a81997-01-16 00:15:11 +0000444
445
Guido van Rossum18468821994-06-20 07:49:28 +0000446static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000447Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000448{
Barry Warsawfa701a81997-01-16 00:15:11 +0000449 int argc;
450 char **argv;
451 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000452
Barry Warsawfa701a81997-01-16 00:15:11 +0000453 if (list == NULL) {
454 Py_INCREF(Py_None);
455 return Py_None;
456 }
Guido van Rossum18468821994-06-20 07:49:28 +0000457
Guido van Rossum00d93061998-05-28 23:06:38 +0000458 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000459 /* Not a list.
460 * Could be a quoted string containing funnies, e.g. {"}.
461 * Return the string itself.
462 */
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000463 return PyUnicode_FromString(list);
Barry Warsawfa701a81997-01-16 00:15:11 +0000464 }
Guido van Rossum18468821994-06-20 07:49:28 +0000465
Barry Warsawfa701a81997-01-16 00:15:11 +0000466 if (argc == 0)
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000467 v = PyUnicode_FromString("");
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 else if (argc == 1)
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000469 v = PyUnicode_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000470 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 int i;
472 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000473
Barry Warsawfa701a81997-01-16 00:15:11 +0000474 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000475 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 Py_DECREF(v);
477 v = NULL;
478 break;
479 }
480 PyTuple_SetItem(v, i, w);
481 }
482 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000483 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000484 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000485}
486
Martin v. Löwisffad6332002-11-26 09:28:05 +0000487/* In some cases, Tcl will still return strings that are supposed to be
488 lists. SplitObj walks through a nested tuple, finding string objects that
489 need to be split. */
490
Martin v. Löwis59683e82008-06-13 07:50:45 +0000491static PyObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000492SplitObj(PyObject *arg)
493{
494 if (PyTuple_Check(arg)) {
495 int i, size;
496 PyObject *elem, *newelem, *result;
497
498 size = PyTuple_Size(arg);
499 result = NULL;
500 /* Recursively invoke SplitObj for all tuple items.
501 If this does not return a new object, no action is
502 needed. */
503 for(i = 0; i < size; i++) {
504 elem = PyTuple_GetItem(arg, i);
505 newelem = SplitObj(elem);
506 if (!newelem) {
507 Py_XDECREF(result);
508 return NULL;
509 }
510 if (!result) {
511 int k;
512 if (newelem == elem) {
513 Py_DECREF(newelem);
514 continue;
515 }
516 result = PyTuple_New(size);
517 if (!result)
518 return NULL;
519 for(k = 0; k < i; k++) {
520 elem = PyTuple_GetItem(arg, k);
521 Py_INCREF(elem);
522 PyTuple_SetItem(result, k, elem);
523 }
524 }
525 PyTuple_SetItem(result, i, newelem);
526 }
527 if (result)
528 return result;
529 /* Fall through, returning arg. */
530 }
Christian Heimes72b710a2008-05-26 13:28:38 +0000531 else if (PyBytes_Check(arg)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000532 int argc;
533 char **argv;
Christian Heimes72b710a2008-05-26 13:28:38 +0000534 char *list = PyBytes_AsString(arg);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000535
536 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
537 Py_INCREF(arg);
538 return arg;
539 }
540 Tcl_Free(FREECAST argv);
541 if (argc > 1)
Christian Heimes72b710a2008-05-26 13:28:38 +0000542 return Split(PyBytes_AsString(arg));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000543 /* Fall through, returning arg. */
544 }
545 Py_INCREF(arg);
546 return arg;
547}
Barry Warsawfa701a81997-01-16 00:15:11 +0000548
549
Guido van Rossum18468821994-06-20 07:49:28 +0000550/**** Tkapp Object ****/
551
552#ifndef WITH_APPINIT
553int
Fred Drake509d79a2000-07-08 04:04:38 +0000554Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000555{
Barry Warsawfa701a81997-01-16 00:15:11 +0000556 Tk_Window main;
David Aschere2b4b322004-02-18 05:59:53 +0000557 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000558
Barry Warsawfa701a81997-01-16 00:15:11 +0000559 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000560 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000561 return TCL_ERROR;
562 }
David Aschere2b4b322004-02-18 05:59:53 +0000563 _tkinter_skip_tk_init = Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
564 if (_tkinter_skip_tk_init == NULL || strcmp(_tkinter_skip_tk_init, "1") != 0) {
565 main = Tk_MainWindow(interp);
566 if (Tk_Init(interp) == TCL_ERROR) {
567 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
568 return TCL_ERROR;
569 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 }
571 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000572}
573#endif /* !WITH_APPINIT */
574
Guido van Rossum18468821994-06-20 07:49:28 +0000575
Barry Warsawfa701a81997-01-16 00:15:11 +0000576
577
578/* Initialize the Tk application; see the `main' function in
579 * `tkMain.c'.
580 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000581
Thomas Wouters58d05102000-07-24 14:43:35 +0000582static void EnableEventHook(void); /* Forward */
583static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000584
Barry Warsawfa701a81997-01-16 00:15:11 +0000585static TkappObject *
Martin v. Löwisb9279bc2008-04-05 19:47:23 +0000586Tkapp_New(char *screenName, char *className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000587 int interactive, int wantobjects, int wantTk, int sync, char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000588{
589 TkappObject *v;
590 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000591
Guido van Rossumb18618d2000-05-03 23:44:39 +0000592 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000593 if (v == NULL)
594 return NULL;
595
596 v->interp = Tcl_CreateInterp();
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000597 v->wantobjects = wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000598 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
599 TCL_GLOBAL_ONLY) != NULL;
600 v->thread_id = Tcl_GetCurrentThread();
601 v->dispatching = 0;
602
603#ifndef TCL_THREADS
604 if (v->threaded) {
605 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
606 Py_DECREF(v);
607 return 0;
608 }
609#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000610#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000611 if (v->threaded && tcl_lock) {
612 /* If Tcl is threaded, we don't need the lock. */
613 PyThread_free_lock(tcl_lock);
614 tcl_lock = NULL;
615 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000616#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000617
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000618 v->BooleanType = Tcl_GetObjType("boolean");
619 v->ByteArrayType = Tcl_GetObjType("bytearray");
620 v->DoubleType = Tcl_GetObjType("double");
621 v->IntType = Tcl_GetObjType("int");
622 v->ListType = Tcl_GetObjType("list");
623 v->ProcBodyType = Tcl_GetObjType("procbody");
624 v->StringType = Tcl_GetObjType("string");
625
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000626 /* Delete the 'exit' command, which can screw things up */
627 Tcl_DeleteCommand(v->interp, "exit");
628
Barry Warsawfa701a81997-01-16 00:15:11 +0000629 if (screenName != NULL)
630 Tcl_SetVar2(v->interp, "env", "DISPLAY",
631 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000632
Barry Warsawfa701a81997-01-16 00:15:11 +0000633 if (interactive)
634 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
635 else
636 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000637
Barry Warsawfa701a81997-01-16 00:15:11 +0000638 /* This is used to get the application class for Tk 4.1 and up */
639 argv0 = (char*)ckalloc(strlen(className) + 1);
640 if (!argv0) {
641 PyErr_NoMemory();
642 Py_DECREF(v);
643 return NULL;
644 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000645
Barry Warsawfa701a81997-01-16 00:15:11 +0000646 strcpy(argv0, className);
Neal Norwitz9dbc7dd2005-12-19 06:08:59 +0000647 if (isupper(Py_CHARMASK(argv0[0])))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000648 argv0[0] = tolower(Py_CHARMASK(argv0[0]));
Barry Warsawfa701a81997-01-16 00:15:11 +0000649 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
650 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000651
David Aschere2b4b322004-02-18 05:59:53 +0000652 if (! wantTk) {
653 Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
654 }
655
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000656 /* some initial arguments need to be in argv */
657 if (sync || use) {
Tim Peters51fa3b72004-08-04 02:16:48 +0000658 char *args;
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000659 int len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000660
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000661 if (sync)
662 len += sizeof "-sync";
663 if (use)
664 len += strlen(use) + sizeof "-use ";
665
Tim Peters51fa3b72004-08-04 02:16:48 +0000666 args = (char*)ckalloc(len);
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000667 if (!args) {
668 PyErr_NoMemory();
669 Py_DECREF(v);
670 return NULL;
671 }
672
673 args[0] = '\0';
674 if (sync)
675 strcat(args, "-sync");
676 if (use) {
677 if (sync)
678 strcat(args, " ");
679 strcat(args, "-use ");
680 strcat(args, use);
681 }
682
683 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
684 ckfree(args);
685 }
686
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000687 if (Tcl_AppInit(v->interp) != TCL_OK) {
688 PyObject *result = Tkinter_Error((PyObject *)v);
689 Py_DECREF((PyObject *)v);
690 return (TkappObject *)result;
691 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000692
Guido van Rossum7bf15641998-05-22 18:28:17 +0000693 EnableEventHook();
694
Barry Warsawfa701a81997-01-16 00:15:11 +0000695 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000696}
697
Barry Warsawfa701a81997-01-16 00:15:11 +0000698
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000699static void
700Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
701 Tcl_Condition *cond, Tcl_Mutex *mutex)
702{
703 Py_BEGIN_ALLOW_THREADS;
704 Tcl_MutexLock(mutex);
705 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
706 Tcl_ThreadAlert(self->thread_id);
707 Tcl_ConditionWait(cond, mutex, NULL);
708 Tcl_MutexUnlock(mutex);
709 Py_END_ALLOW_THREADS
710}
711
Barry Warsawfa701a81997-01-16 00:15:11 +0000712
Guido van Rossum18468821994-06-20 07:49:28 +0000713/** Tcl Eval **/
714
Martin v. Löwisffad6332002-11-26 09:28:05 +0000715typedef struct {
716 PyObject_HEAD
717 Tcl_Obj *value;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000718 PyObject *string; /* This cannot cause cycles. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000719} PyTclObject;
720
Neal Norwitz227b5332006-03-22 09:28:35 +0000721static PyTypeObject PyTclObject_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000722#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
723
724static PyObject *
725newPyTclObject(Tcl_Obj *arg)
726{
727 PyTclObject *self;
728 self = PyObject_New(PyTclObject, &PyTclObject_Type);
729 if (self == NULL)
730 return NULL;
731 Tcl_IncrRefCount(arg);
732 self->value = arg;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000733 self->string = NULL;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000734 return (PyObject*)self;
735}
736
737static void
738PyTclObject_dealloc(PyTclObject *self)
739{
740 Tcl_DecrRefCount(self->value);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000741 Py_XDECREF(self->string);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000742 PyObject_Del(self);
743}
744
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000745static char*
746PyTclObject_TclString(PyObject *self)
747{
748 return Tcl_GetString(((PyTclObject*)self)->value);
749}
750
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000751/* Like _str, but create Unicode if necessary. */
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000752PyDoc_STRVAR(PyTclObject_string__doc__,
Christian Heimesb2b62622007-11-22 05:56:35 +0000753"the string representation of this object, either as str or bytes");
Martin v. Löwis39195712003-01-04 00:33:13 +0000754
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000755static PyObject *
756PyTclObject_string(PyTclObject *self, void *ignored)
757{
758 char *s;
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000759 int len;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000760 if (!self->string) {
761 s = Tcl_GetStringFromObj(self->value, &len);
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000762 self->string = PyUnicode_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000763 if (!self->string)
764 return NULL;
765 }
766 Py_INCREF(self->string);
767 return self->string;
768}
769
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000770static PyObject *
Walter Dörwald6720d912007-07-12 12:12:25 +0000771PyTclObject_str(PyTclObject *self, void *ignored)
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000772{
773 char *s;
774 int len;
775 if (self->string && PyUnicode_Check(self->string)) {
776 Py_INCREF(self->string);
777 return self->string;
778 }
779 /* XXX Could chache result if it is non-ASCII. */
780 s = Tcl_GetStringFromObj(self->value, &len);
781 return PyUnicode_DecodeUTF8(s, len, "strict");
782}
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000783
Martin v. Löwisffad6332002-11-26 09:28:05 +0000784static PyObject *
785PyTclObject_repr(PyTclObject *self)
786{
Walter Dörwald7569dfe2007-05-19 21:49:49 +0000787 return PyUnicode_FromFormat("<%s object at %p>",
788 self->value->typePtr->name, self->value);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000789}
790
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000791static int
792PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
793{
794 int res;
795 res = strcmp(Tcl_GetString(self->value),
796 Tcl_GetString(other->value));
797 if (res < 0) return -1;
798 if (res > 0) return 1;
799 return 0;
800}
801
Martin v. Löwis39195712003-01-04 00:33:13 +0000802PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
803
Martin v. Löwisffad6332002-11-26 09:28:05 +0000804static PyObject*
805get_typename(PyTclObject* obj, void* ignored)
806{
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000807 return PyUnicode_FromString(obj->value->typePtr->name);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000808}
809
Martin v. Löwis39195712003-01-04 00:33:13 +0000810
Martin v. Löwisffad6332002-11-26 09:28:05 +0000811static PyGetSetDef PyTclObject_getsetlist[] = {
Martin v. Löwis39195712003-01-04 00:33:13 +0000812 {"typename", (getter)get_typename, NULL, get_typename__doc__},
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000813 {"string", (getter)PyTclObject_string, NULL,
Martin v. Löwis39195712003-01-04 00:33:13 +0000814 PyTclObject_string__doc__},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000815 {0},
816};
817
Neal Norwitz227b5332006-03-22 09:28:35 +0000818static PyTypeObject PyTclObject_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000819 PyVarObject_HEAD_INIT(NULL, 0)
Martin v. Löwisffad6332002-11-26 09:28:05 +0000820 "_tkinter.Tcl_Obj", /*tp_name*/
821 sizeof(PyTclObject), /*tp_basicsize*/
822 0, /*tp_itemsize*/
823 /* methods */
824 (destructor)PyTclObject_dealloc, /*tp_dealloc*/
825 0, /*tp_print*/
826 0, /*tp_getattr*/
827 0, /*tp_setattr*/
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000828 (cmpfunc)PyTclObject_cmp, /*tp_compare*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000829 (reprfunc)PyTclObject_repr, /*tp_repr*/
830 0, /*tp_as_number*/
831 0, /*tp_as_sequence*/
832 0, /*tp_as_mapping*/
833 0, /*tp_hash*/
834 0, /*tp_call*/
835 (reprfunc)PyTclObject_str, /*tp_str*/
Jason Tishlerfb8595d2003-01-06 12:41:26 +0000836 PyObject_GenericGetAttr,/*tp_getattro*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000837 0, /*tp_setattro*/
838 0, /*tp_as_buffer*/
839 Py_TPFLAGS_DEFAULT, /*tp_flags*/
840 0, /*tp_doc*/
841 0, /*tp_traverse*/
842 0, /*tp_clear*/
843 0, /*tp_richcompare*/
844 0, /*tp_weaklistoffset*/
845 0, /*tp_iter*/
846 0, /*tp_iternext*/
Walter Dörwald6720d912007-07-12 12:12:25 +0000847 0, /*tp_methods*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000848 0, /*tp_members*/
849 PyTclObject_getsetlist, /*tp_getset*/
850 0, /*tp_base*/
851 0, /*tp_dict*/
852 0, /*tp_descr_get*/
853 0, /*tp_descr_set*/
854 0, /*tp_dictoffset*/
855 0, /*tp_init*/
856 0, /*tp_alloc*/
857 0, /*tp_new*/
858 0, /*tp_free*/
859 0, /*tp_is_gc*/
860};
861
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000862static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000863AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000864{
865 Tcl_Obj *result;
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +0000866 long longVal;
867 int overflow;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000868
Christian Heimes72b710a2008-05-26 13:28:38 +0000869 if (PyBytes_Check(value))
870 return Tcl_NewStringObj(PyBytes_AS_STRING(value),
871 PyBytes_GET_SIZE(value));
Martin v. Löwis70c3dda2003-01-22 09:17:38 +0000872 else if (PyBool_Check(value))
873 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +0000874 else if (PyLong_CheckExact(value) &&
875 ((longVal = PyLong_AsLongAndOverflow(value, &overflow)),
876 !overflow)) {
877 /* If there is an overflow in the long conversion,
878 fall through to default object handling. */
879 return Tcl_NewLongObj(longVal);
880 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000881 else if (PyFloat_Check(value))
882 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
883 else if (PyTuple_Check(value)) {
884 Tcl_Obj **argv = (Tcl_Obj**)
885 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
886 int i;
887 if(!argv)
888 return 0;
889 for(i=0;i<PyTuple_Size(value);i++)
890 argv[i] = AsObj(PyTuple_GetItem(value,i));
891 result = Tcl_NewListObj(PyTuple_Size(value), argv);
892 ckfree(FREECAST argv);
893 return result;
894 }
895 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000896 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000897 Py_ssize_t size = PyUnicode_GET_SIZE(value);
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000898 /* This #ifdef assumes that Tcl uses UCS-2.
899 See TCL_UTF_MAX test above. */
Martin v. Löwis6f29ff32003-04-16 20:34:55 +0000900#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
Christian Heimesa34706f2008-01-04 03:06:10 +0000901 Tcl_UniChar *outbuf = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000902 Py_ssize_t i;
Christian Heimesa34706f2008-01-04 03:06:10 +0000903 size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
904 if (allocsize >= size)
905 outbuf = (Tcl_UniChar*)ckalloc(allocsize);
906 /* Else overflow occurred, and we take the next exit */
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000907 if (!outbuf) {
908 PyErr_NoMemory();
909 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000910 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000911 for (i = 0; i < size; i++) {
912 if (inbuf[i] >= 0x10000) {
913 /* Tcl doesn't do UTF-16, yet. */
914 PyErr_SetString(PyExc_ValueError,
915 "unsupported character");
916 ckfree(FREECAST outbuf);
917 return NULL;
918 }
919 outbuf[i] = inbuf[i];
920 }
921 result = Tcl_NewUnicodeObj(outbuf, size);
922 ckfree(FREECAST outbuf);
923 return result;
924#else
925 return Tcl_NewUnicodeObj(inbuf, size);
926#endif
927
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000928 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000929 else if(PyTclObject_Check(value)) {
930 Tcl_Obj *v = ((PyTclObject*)value)->value;
931 Tcl_IncrRefCount(v);
932 return v;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000933 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000934 else {
935 PyObject *v = PyObject_Str(value);
936 if (!v)
937 return 0;
938 result = AsObj(v);
939 Py_DECREF(v);
940 return result;
941 }
942}
943
Martin v. Löwisffad6332002-11-26 09:28:05 +0000944static PyObject*
945FromObj(PyObject* tkapp, Tcl_Obj *value)
946{
947 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000948 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000949
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000950 if (value->typePtr == NULL) {
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000951 return PyUnicode_FromStringAndSize(value->bytes,
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000952 value->length);
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000953 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000954
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000955 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000956 result = value->internalRep.longValue ? Py_True : Py_False;
957 Py_INCREF(result);
958 return result;
959 }
960
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000961 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000962 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +0000963 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Christian Heimes72b710a2008-05-26 13:28:38 +0000964 return PyBytes_FromStringAndSize(data, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000965 }
966
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000967 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000968 return PyFloat_FromDouble(value->internalRep.doubleValue);
969 }
970
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000971 if (value->typePtr == app->IntType) {
Christian Heimes217cfd12007-12-02 14:31:20 +0000972 return PyLong_FromLong(value->internalRep.longValue);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000973 }
974
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000975 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000976 int size;
977 int i, status;
978 PyObject *elem;
979 Tcl_Obj *tcl_elem;
980
981 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
982 if (status == TCL_ERROR)
983 return Tkinter_Error(tkapp);
984 result = PyTuple_New(size);
985 if (!result)
986 return NULL;
987 for (i = 0; i < size; i++) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000988 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
Martin v. Löwisffad6332002-11-26 09:28:05 +0000989 value, i, &tcl_elem);
990 if (status == TCL_ERROR) {
991 Py_DECREF(result);
992 return Tkinter_Error(tkapp);
993 }
994 elem = FromObj(tkapp, tcl_elem);
995 if (!elem) {
996 Py_DECREF(result);
997 return NULL;
998 }
999 PyTuple_SetItem(result, i, elem);
1000 }
1001 return result;
1002 }
1003
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001004 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001005 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +00001006 }
1007
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001008 if (value->typePtr == app->StringType) {
Martin v. Löwis6f29ff32003-04-16 20:34:55 +00001009#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
Martin v. Löwisffad6332002-11-26 09:28:05 +00001010 PyObject *result;
1011 int size;
1012 Tcl_UniChar *input;
1013 Py_UNICODE *output;
1014
1015 size = Tcl_GetCharLength(value);
1016 result = PyUnicode_FromUnicode(NULL, size);
1017 if (!result)
1018 return NULL;
1019 input = Tcl_GetUnicode(value);
1020 output = PyUnicode_AS_UNICODE(result);
1021 while (size--)
1022 *output++ = *input++;
1023 return result;
1024#else
1025 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1026 Tcl_GetCharLength(value));
1027#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +00001028 }
1029
1030 return newPyTclObject(value);
1031}
1032
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001033/* This mutex synchronizes inter-thread command calls. */
1034
1035TCL_DECLARE_MUTEX(call_mutex)
1036
1037typedef struct Tkapp_CallEvent {
1038 Tcl_Event ev; /* Must be first */
1039 TkappObject *self;
1040 PyObject *args;
1041 int flags;
1042 PyObject **res;
1043 PyObject **exc_type, **exc_value, **exc_tb;
1044 Tcl_Condition done;
1045} Tkapp_CallEvent;
1046
1047void
1048Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001049{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001050 int i;
1051 for (i = 0; i < objc; i++)
1052 Tcl_DecrRefCount(objv[i]);
1053 if (objv != objStore)
1054 ckfree(FREECAST objv);
1055}
Guido van Rossum18468821994-06-20 07:49:28 +00001056
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001057/* Convert Python objects to Tcl objects. This must happen in the
1058 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001059
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001060static Tcl_Obj**
1061Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1062{
1063 Tcl_Obj **objv = objStore;
Martin v. Löwis7d134952002-12-12 19:05:48 +00001064 int objc = 0, i;
Guido van Rossum212643f1998-04-29 16:22:14 +00001065 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +00001066 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001067
Guido van Rossum212643f1998-04-29 16:22:14 +00001068 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +00001069 objv[0] = AsObj(args);
1070 if (objv[0] == 0)
1071 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001072 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +00001073 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001074 }
1075 else {
Guido van Rossum632de272000-03-29 00:19:50 +00001076 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001077
Guido van Rossum632de272000-03-29 00:19:50 +00001078 if (objc > ARGSZ) {
1079 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1080 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001081 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +00001082 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +00001083 goto finally;
1084 }
1085 }
1086
Guido van Rossum632de272000-03-29 00:19:50 +00001087 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001088 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +00001089 if (v == Py_None) {
1090 objc = i;
1091 break;
1092 }
Guido van Rossum632de272000-03-29 00:19:50 +00001093 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +00001094 if (!objv[i]) {
1095 /* Reset objc, so it attempts to clear
1096 objects only up to i. */
1097 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +00001098 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001099 }
Guido van Rossum632de272000-03-29 00:19:50 +00001100 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001101 }
1102 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001103 *pobjc = objc;
1104 return objv;
1105finally:
1106 Tkapp_CallDeallocArgs(objv, objStore, objc);
1107 return NULL;
1108}
Guido van Rossum212643f1998-04-29 16:22:14 +00001109
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001110/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001111
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001112static PyObject*
1113Tkapp_CallResult(TkappObject *self)
1114{
1115 PyObject *res = NULL;
1116 if(self->wantobjects) {
1117 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001118 /* Not sure whether the IncrRef is necessary, but something
1119 may overwrite the interpreter result while we are
1120 converting it. */
1121 Tcl_IncrRefCount(value);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001122 res = FromObj((PyObject*)self, value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001123 Tcl_DecrRefCount(value);
1124 } else {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001125 const char *s = Tcl_GetStringResult(self->interp);
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001126 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001127
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001128 res = PyUnicode_FromStringAndSize(s, (int)(p-s));
Guido van Rossum990f5c62000-05-04 15:07:16 +00001129 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001130 return res;
1131}
Guido van Rossum632de272000-03-29 00:19:50 +00001132
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001133/* Tkapp_CallProc is the event procedure that is executed in the context of
1134 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1135 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001136
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001137static int
1138Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1139{
1140 Tcl_Obj *objStore[ARGSZ];
1141 Tcl_Obj **objv;
1142 int objc;
1143 int i;
1144 ENTER_PYTHON
1145 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1146 if (!objv) {
1147 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1148 *(e->res) = NULL;
1149 }
1150 LEAVE_PYTHON
1151 if (!objv)
1152 goto done;
1153 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1154 ENTER_PYTHON
1155 if (i == TCL_ERROR) {
1156 *(e->res) = NULL;
1157 *(e->exc_type) = NULL;
1158 *(e->exc_tb) = NULL;
1159 *(e->exc_value) = PyObject_CallFunction(
1160 Tkinter_TclError, "s",
1161 Tcl_GetStringResult(e->self->interp));
1162 }
1163 else {
1164 *(e->res) = Tkapp_CallResult(e->self);
1165 }
1166 LEAVE_PYTHON
1167 done:
1168 /* Wake up calling thread. */
1169 Tcl_MutexLock(&call_mutex);
1170 Tcl_ConditionNotify(&e->done);
1171 Tcl_MutexUnlock(&call_mutex);
1172 return 1;
1173}
1174
1175/* This is the main entry point for calling a Tcl command.
1176 It supports three cases, with regard to threading:
1177 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1178 the context of the calling thread.
1179 2. Tcl is threaded, caller of the command is in the interpreter thread:
1180 Execute the command in the calling thread. Since the Tcl lock will
1181 not be used, we can merge that with case 1.
1182 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1183 the interpreter thread. Allocation of Tcl objects needs to occur in the
1184 interpreter thread, so we ship the PyObject* args to the target thread,
1185 and perform processing there. */
1186
1187static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001188Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001189{
1190 Tcl_Obj *objStore[ARGSZ];
1191 Tcl_Obj **objv = NULL;
1192 int objc, i;
1193 PyObject *res = NULL;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001194 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001195 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
1196 int flags = TCL_EVAL_DIRECT;
1197
Guido van Rossum992d4a32007-07-11 13:09:30 +00001198 /* If args is a single tuple, replace with contents of tuple */
1199 if (1 == PyTuple_Size(args)){
1200 PyObject* item = PyTuple_GetItem(args, 0);
1201 if (PyTuple_Check(item))
1202 args = item;
1203 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001204#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001205 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1206 /* We cannot call the command directly. Instead, we must
1207 marshal the parameters to the interpreter thread. */
1208 Tkapp_CallEvent *ev;
1209 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001210 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001211 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001212 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1213 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1214 ev->self = self;
1215 ev->args = args;
1216 ev->res = &res;
1217 ev->exc_type = &exc_type;
1218 ev->exc_value = &exc_value;
1219 ev->exc_tb = &exc_tb;
1220 ev->done = (Tcl_Condition)0;
1221
1222 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &call_mutex);
1223
1224 if (res == NULL) {
1225 if (exc_type)
1226 PyErr_Restore(exc_type, exc_value, exc_tb);
1227 else
1228 PyErr_SetObject(Tkinter_TclError, exc_value);
1229 }
1230 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001231 else
Martin v. Löwisa9656492003-03-30 08:44:58 +00001232#endif
1233 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001234
1235 objv = Tkapp_CallArgs(args, objStore, &objc);
1236 if (!objv)
1237 return NULL;
1238
1239 ENTER_TCL
1240
1241 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1242
1243 ENTER_OVERLAP
1244
1245 if (i == TCL_ERROR)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001246 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001247 else
1248 res = Tkapp_CallResult(self);
1249
1250 LEAVE_OVERLAP_TCL
1251
1252 Tkapp_CallDeallocArgs(objv, objStore, objc);
1253 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001254 return res;
1255}
1256
1257
1258static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001259Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001260{
Guido van Rossum212643f1998-04-29 16:22:14 +00001261 /* Could do the same here as for Tkapp_Call(), but this is not used
1262 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1263 way for the user to do what all its Global* variants do (save and
1264 reset the scope pointer, call the local version, restore the saved
1265 scope pointer). */
1266
Guido van Rossum62320c91998-06-15 04:36:09 +00001267 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001268 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001269
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001270 CHECK_TCL_APPARTMENT;
1271
Guido van Rossum62320c91998-06-15 04:36:09 +00001272 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001273 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001274 int err;
1275 ENTER_TCL
1276 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001277 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001278 if (err == TCL_ERROR)
1279 res = Tkinter_Error(self);
1280 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001281 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001282 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001283 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001284 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001285
1286 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001287}
1288
1289static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001290Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001291{
Barry Warsawfa701a81997-01-16 00:15:11 +00001292 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001293 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001294 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001295
Guido van Rossum43713e52000-02-29 13:59:29 +00001296 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001297 return NULL;
1298
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001299 CHECK_TCL_APPARTMENT;
1300
Guido van Rossum00d93061998-05-28 23:06:38 +00001301 ENTER_TCL
1302 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001303 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001304 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001305 res = Tkinter_Error(self);
1306 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001307 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001308 LEAVE_OVERLAP_TCL
1309 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001310}
1311
1312static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001313Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001314{
Barry Warsawfa701a81997-01-16 00:15:11 +00001315 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001316 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001317 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001318
Guido van Rossum43713e52000-02-29 13:59:29 +00001319 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001320 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001321
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001322 CHECK_TCL_APPARTMENT;
1323
Guido van Rossum00d93061998-05-28 23:06:38 +00001324 ENTER_TCL
1325 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001326 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001327 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001328 res = Tkinter_Error(self);
1329 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001330 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001331 LEAVE_OVERLAP_TCL
1332 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001333}
1334
1335static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001336Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001337{
Barry Warsawfa701a81997-01-16 00:15:11 +00001338 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001339 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001340 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001341
Guido van Rossum43713e52000-02-29 13:59:29 +00001342 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001343 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001344
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001345 CHECK_TCL_APPARTMENT;
1346
Guido van Rossum00d93061998-05-28 23:06:38 +00001347 ENTER_TCL
1348 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001349 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001350 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001351 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001352
Guido van Rossum62320c91998-06-15 04:36:09 +00001353 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001354 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001355 LEAVE_OVERLAP_TCL
1356 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001357}
1358
1359static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001360Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001361{
Barry Warsawfa701a81997-01-16 00:15:11 +00001362 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001363 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001364 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001365
Guido van Rossum35d43371997-08-02 00:09:09 +00001366 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001367 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001368
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001369 CHECK_TCL_APPARTMENT;
1370
Guido van Rossum00d93061998-05-28 23:06:38 +00001371 ENTER_TCL
1372 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001373 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001374 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001375 res = Tkinter_Error(self);
1376 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001377 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001378 LEAVE_OVERLAP_TCL
1379 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001380}
1381
1382static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001383Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001384{
Barry Warsawfa701a81997-01-16 00:15:11 +00001385 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001386
Guido van Rossum43713e52000-02-29 13:59:29 +00001387 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001388 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001389 CHECK_TCL_APPARTMENT;
1390
Guido van Rossum00d93061998-05-28 23:06:38 +00001391 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001392 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001393 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001394
Barry Warsawfa701a81997-01-16 00:15:11 +00001395 Py_INCREF(Py_None);
1396 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001397}
1398
Barry Warsawfa701a81997-01-16 00:15:11 +00001399
1400
Guido van Rossum18468821994-06-20 07:49:28 +00001401/** Tcl Variable **/
1402
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001403TCL_DECLARE_MUTEX(var_mutex)
1404
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001405typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001406typedef struct VarEvent {
1407 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001408 PyObject *self;
1409 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001410 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001411 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001412 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001413 PyObject **exc_type;
1414 PyObject **exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001415 Tcl_Condition cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001416} VarEvent;
1417
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001418static int
1419varname_converter(PyObject *in, void *_out)
1420{
1421 char **out = (char**)_out;
Christian Heimes72b710a2008-05-26 13:28:38 +00001422 if (PyBytes_Check(in)) {
1423 *out = PyBytes_AsString(in);
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001424 return 1;
1425 }
Guido van Rossumf761e102007-07-23 18:34:37 +00001426 if (PyUnicode_Check(in)) {
1427 *out = PyUnicode_AsString(in);
1428 return 1;
1429 }
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001430 if (PyTclObject_Check(in)) {
1431 *out = PyTclObject_TclString(in);
1432 return 1;
1433 }
1434 /* XXX: Should give diagnostics. */
1435 return 0;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001436}
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001437
Martin v. Löwis59683e82008-06-13 07:50:45 +00001438static void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001439var_perform(VarEvent *ev)
1440{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001441 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1442 if (!*(ev->res)) {
1443 PyObject *exc, *val, *tb;
1444 PyErr_Fetch(&exc, &val, &tb);
1445 PyErr_NormalizeException(&exc, &val, &tb);
1446 *(ev->exc_type) = exc;
1447 *(ev->exc_val) = val;
1448 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001449 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001450
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001451}
1452
1453static int
1454var_proc(VarEvent* ev, int flags)
1455{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001456 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001457 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001458 Tcl_MutexLock(&var_mutex);
1459 Tcl_ConditionNotify(&ev->cond);
1460 Tcl_MutexUnlock(&var_mutex);
1461 LEAVE_PYTHON
1462 return 1;
1463}
1464
1465static PyObject*
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001466var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001467{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001468 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisa9656492003-03-30 08:44:58 +00001469#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001470 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001471 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001472 VarEvent *ev;
1473 PyObject *res, *exc_type, *exc_val;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001474
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001475 /* The current thread is not the interpreter thread. Marshal
1476 the call to the interpreter thread, then wait for
1477 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001478 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001479 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001480
1481 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1482
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001483 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001484 ev->args = args;
1485 ev->flags = flags;
1486 ev->func = func;
1487 ev->res = &res;
1488 ev->exc_type = &exc_type;
1489 ev->exc_val = &exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001490 ev->cond = NULL;
1491 ev->ev.proc = (Tcl_EventProc*)var_proc;
1492 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001493 if (!res) {
1494 PyErr_SetObject(exc_type, exc_val);
1495 Py_DECREF(exc_type);
1496 Py_DECREF(exc_val);
1497 return NULL;
1498 }
1499 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001500 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001501#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001502 /* Tcl is not threaded, or this is the interpreter thread. */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001503 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001504}
1505
Guido van Rossum18468821994-06-20 07:49:28 +00001506static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001507SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001508{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001509 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001510 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001511 PyObject *res = NULL;
1512 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001513
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001514 if (PyArg_ParseTuple(args, "O&O:setvar",
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001515 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001516 /* XXX Acquire tcl lock??? */
1517 newval = AsObj(newValue);
1518 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001519 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001520 ENTER_TCL
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001521 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001522 newval, flags);
1523 ENTER_OVERLAP
1524 if (!ok)
1525 Tkinter_Error(self);
1526 else {
1527 res = Py_None;
1528 Py_INCREF(res);
1529 }
1530 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001531 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001532 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001533 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001534 if (PyArg_ParseTuple(args, "ssO:setvar",
1535 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001536 /* XXX must hold tcl lock already??? */
1537 newval = AsObj(newValue);
1538 ENTER_TCL
1539 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1540 ENTER_OVERLAP
1541 if (!ok)
1542 Tkinter_Error(self);
1543 else {
1544 res = Py_None;
1545 Py_INCREF(res);
1546 }
1547 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001548 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001549 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001550 return NULL;
1551 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001552 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001553 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001554}
1555
1556static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001557Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001558{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001559 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001560}
1561
1562static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001563Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001564{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001565 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001566}
1567
Barry Warsawfa701a81997-01-16 00:15:11 +00001568
1569
Guido van Rossum18468821994-06-20 07:49:28 +00001570static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001571GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001572{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001573 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001574 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001575 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001576
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001577 if (!PyArg_ParseTuple(args, "O&|s:getvar",
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001578 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001579 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001580
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001581 ENTER_TCL
1582 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1583 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001584 if (tres == NULL) {
1585 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1586 } else {
1587 if (((TkappObject*)self)->wantobjects) {
1588 res = FromObj(self, tres);
1589 }
1590 else {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001591 res = PyUnicode_FromString(Tcl_GetString(tres));
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001592 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001593 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001594 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001595 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001596}
1597
1598static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001599Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001600{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001601 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001602}
1603
1604static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001605Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001606{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001607 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001608}
1609
Barry Warsawfa701a81997-01-16 00:15:11 +00001610
1611
Guido van Rossum18468821994-06-20 07:49:28 +00001612static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001613UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001614{
Guido van Rossum35d43371997-08-02 00:09:09 +00001615 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001616 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001617 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001618
Guido van Rossum43713e52000-02-29 13:59:29 +00001619 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001620 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001621
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001622 ENTER_TCL
1623 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1624 ENTER_OVERLAP
1625 if (code == TCL_ERROR)
1626 res = Tkinter_Error(self);
1627 else {
1628 Py_INCREF(Py_None);
1629 res = Py_None;
1630 }
1631 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001632 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001633}
1634
1635static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001636Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001637{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001638 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001639}
1640
1641static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001642Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001643{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001644 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001645}
1646
Barry Warsawfa701a81997-01-16 00:15:11 +00001647
1648
Guido van Rossum18468821994-06-20 07:49:28 +00001649/** Tcl to Python **/
1650
1651static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001652Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001653{
Barry Warsawfa701a81997-01-16 00:15:11 +00001654 char *s;
1655 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001656
Martin v. Löwisffad6332002-11-26 09:28:05 +00001657 if (PyTuple_Size(args) == 1) {
1658 PyObject* o = PyTuple_GetItem(args, 0);
Christian Heimes217cfd12007-12-02 14:31:20 +00001659 if (PyLong_Check(o)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001660 Py_INCREF(o);
1661 return o;
1662 }
1663 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001664 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001665 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001666 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001667 return Tkinter_Error(self);
1668 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001669}
1670
1671static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001672Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001673{
Barry Warsawfa701a81997-01-16 00:15:11 +00001674 char *s;
1675 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001676
Martin v. Löwisffad6332002-11-26 09:28:05 +00001677 if (PyTuple_Size(args) == 1) {
1678 PyObject *o = PyTuple_GetItem(args, 0);
1679 if (PyFloat_Check(o)) {
1680 Py_INCREF(o);
1681 return o;
1682 }
1683 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001684 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001685 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001686 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001687 return Tkinter_Error(self);
1688 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001689}
1690
1691static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001692Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001693{
Barry Warsawfa701a81997-01-16 00:15:11 +00001694 char *s;
1695 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001696
Martin v. Löwisffad6332002-11-26 09:28:05 +00001697 if (PyTuple_Size(args) == 1) {
1698 PyObject *o = PyTuple_GetItem(args, 0);
Christian Heimes217cfd12007-12-02 14:31:20 +00001699 if (PyLong_Check(o)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001700 Py_INCREF(o);
1701 return o;
1702 }
1703 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001704 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001705 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001706 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1707 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001708 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001709}
1710
1711static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001712Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001713{
Barry Warsawfa701a81997-01-16 00:15:11 +00001714 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001715 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001716 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001717
Guido van Rossum43713e52000-02-29 13:59:29 +00001718 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001719 return NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001720
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001721 CHECK_TCL_APPARTMENT;
1722
Guido van Rossum00d93061998-05-28 23:06:38 +00001723 ENTER_TCL
1724 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001725 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001726 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001727 res = Tkinter_Error(self);
1728 else
1729 res = Py_BuildValue("s", Tkapp_Result(self));
1730 LEAVE_OVERLAP_TCL
1731 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001732}
1733
1734static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001735Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001736{
Barry Warsawfa701a81997-01-16 00:15:11 +00001737 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001738 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001739 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001740 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001741
Guido van Rossum43713e52000-02-29 13:59:29 +00001742 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001743 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001744
1745 CHECK_TCL_APPARTMENT;
1746
Guido van Rossum00d93061998-05-28 23:06:38 +00001747 ENTER_TCL
1748 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001749 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001750 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001751 res = Tkinter_Error(self);
1752 else
1753 res = Py_BuildValue("l", v);
1754 LEAVE_OVERLAP_TCL
1755 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001756}
1757
1758static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001759Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001760{
Barry Warsawfa701a81997-01-16 00:15:11 +00001761 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001762 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001763 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001764 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001765
Guido van Rossum43713e52000-02-29 13:59:29 +00001766 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001767 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001768 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001769 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001770 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001771 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001772 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001773 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001774 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001775 res = Tkinter_Error(self);
1776 else
1777 res = Py_BuildValue("d", v);
1778 LEAVE_OVERLAP_TCL
1779 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001780}
1781
1782static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001783Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001784{
Barry Warsawfa701a81997-01-16 00:15:11 +00001785 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001786 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001787 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001788 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001789
Guido van Rossum43713e52000-02-29 13:59:29 +00001790 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001791 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001792 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001793 ENTER_TCL
1794 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001795 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001796 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001797 res = Tkinter_Error(self);
1798 else
1799 res = Py_BuildValue("i", v);
1800 LEAVE_OVERLAP_TCL
1801 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001802}
1803
Barry Warsawfa701a81997-01-16 00:15:11 +00001804
1805
Guido van Rossum18468821994-06-20 07:49:28 +00001806static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001807Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001808{
Barry Warsawfa701a81997-01-16 00:15:11 +00001809 char *list;
1810 int argc;
1811 char **argv;
1812 PyObject *v;
1813 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001814
Martin v. Löwisffad6332002-11-26 09:28:05 +00001815 if (PyTuple_Size(args) == 1) {
1816 v = PyTuple_GetItem(args, 0);
1817 if (PyTuple_Check(v)) {
1818 Py_INCREF(v);
1819 return v;
1820 }
1821 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001822 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001823 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001824
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001825 if (Tcl_SplitList(Tkapp_Interp(self), list,
Neal Norwitzd1c55102003-05-29 00:17:03 +00001826 &argc, &argv) == TCL_ERROR) {
1827 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001828 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001829 }
Guido van Rossum18468821994-06-20 07:49:28 +00001830
Barry Warsawfa701a81997-01-16 00:15:11 +00001831 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001832 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001833
Barry Warsawfa701a81997-01-16 00:15:11 +00001834 for (i = 0; i < argc; i++) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001835 PyObject *s = PyUnicode_FromString(argv[i]);
Barry Warsawfa701a81997-01-16 00:15:11 +00001836 if (!s || PyTuple_SetItem(v, i, s)) {
1837 Py_DECREF(v);
1838 v = NULL;
1839 goto finally;
1840 }
1841 }
Guido van Rossum18468821994-06-20 07:49:28 +00001842
Barry Warsawfa701a81997-01-16 00:15:11 +00001843 finally:
1844 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001845 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001846 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001847}
1848
1849static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001850Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001851{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001852 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001853 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001854
Martin v. Löwisffad6332002-11-26 09:28:05 +00001855 if (PyTuple_Size(args) == 1) {
1856 PyObject* o = PyTuple_GetItem(args, 0);
1857 if (PyTuple_Check(o)) {
1858 o = SplitObj(o);
1859 return o;
1860 }
1861 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001862 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001863 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00001864 v = Split(list);
1865 PyMem_Free(list);
1866 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001867}
1868
1869static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001870Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001871{
Barry Warsawfa701a81997-01-16 00:15:11 +00001872 char *s = Merge(args);
1873 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001874
Barry Warsawfa701a81997-01-16 00:15:11 +00001875 if (s) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001876 res = PyUnicode_FromString(s);
Barry Warsawfa701a81997-01-16 00:15:11 +00001877 ckfree(s);
1878 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001879
1880 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001881}
1882
Barry Warsawfa701a81997-01-16 00:15:11 +00001883
1884
Guido van Rossum18468821994-06-20 07:49:28 +00001885/** Tcl Command **/
1886
Guido van Rossum00d93061998-05-28 23:06:38 +00001887/* Client data struct */
1888typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001889 PyObject *self;
1890 PyObject *func;
1891} PythonCmd_ClientData;
1892
1893static int
Fred Drake509d79a2000-07-08 04:04:38 +00001894PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001895{
1896 errorInCmd = 1;
1897 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1898 LEAVE_PYTHON
1899 return TCL_ERROR;
1900}
1901
Guido van Rossum18468821994-06-20 07:49:28 +00001902/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001903 * function or method.
1904 */
Guido van Rossum18468821994-06-20 07:49:28 +00001905static int
Fred Drake509d79a2000-07-08 04:04:38 +00001906PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001907{
Guido van Rossum00d93061998-05-28 23:06:38 +00001908 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Kurt B. Kaiserab45e272007-08-27 01:55:21 +00001909 PyObject *self, *func, *arg, *res, *s;
Guido van Rossum2834b972000-10-06 16:58:26 +00001910 int i, rv;
Christian Heimes57dddfb2008-01-02 18:30:52 +00001911 Tcl_Obj *obj_res;
Guido van Rossum18468821994-06-20 07:49:28 +00001912
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001913 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001914
Barry Warsawfa701a81997-01-16 00:15:11 +00001915 /* TBD: no error checking here since we know, via the
1916 * Tkapp_CreateCommand() that the client data is a two-tuple
1917 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001918 self = data->self;
1919 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001920
Barry Warsawfa701a81997-01-16 00:15:11 +00001921 /* Create argument list (argv1, ..., argvN) */
1922 if (!(arg = PyTuple_New(argc - 1)))
1923 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001924
Barry Warsawfa701a81997-01-16 00:15:11 +00001925 for (i = 0; i < (argc - 1); i++) {
Kurt B. Kaiserab45e272007-08-27 01:55:21 +00001926 if (11 == (i + 1)) { /* the %A arg is the unicode char */
1927 char *a = argv[i + 1];
1928 s = PyUnicode_FromUnicode((Py_UNICODE *) a, strlen(a));
1929 }
1930 else {
1931 s = PyUnicode_FromString(argv[i + 1]);
1932 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001933 if (!s || PyTuple_SetItem(arg, i, s)) {
1934 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001935 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001936 }
1937 }
1938 res = PyEval_CallObject(func, arg);
1939 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001940
Barry Warsawfa701a81997-01-16 00:15:11 +00001941 if (res == NULL)
1942 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001943
Christian Heimes57dddfb2008-01-02 18:30:52 +00001944 obj_res = AsObj(res);
1945 if (obj_res == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001946 Py_DECREF(res);
1947 return PythonCmd_Error(interp);
1948 }
Guido van Rossum2834b972000-10-06 16:58:26 +00001949 else {
Christian Heimes57dddfb2008-01-02 18:30:52 +00001950 Tcl_SetObjResult(Tkapp_Interp(self), obj_res);
Guido van Rossum2834b972000-10-06 16:58:26 +00001951 rv = TCL_OK;
1952 }
1953
Barry Warsawfa701a81997-01-16 00:15:11 +00001954 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00001955
Guido van Rossum00d93061998-05-28 23:06:38 +00001956 LEAVE_PYTHON
1957
Guido van Rossum2834b972000-10-06 16:58:26 +00001958 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001959}
1960
1961static void
Fred Drake509d79a2000-07-08 04:04:38 +00001962PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001963{
Guido van Rossum00d93061998-05-28 23:06:38 +00001964 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1965
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001966 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001967 Py_XDECREF(data->self);
1968 Py_XDECREF(data->func);
1969 PyMem_DEL(data);
1970 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001971}
1972
Barry Warsawfa701a81997-01-16 00:15:11 +00001973
1974
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001975
1976TCL_DECLARE_MUTEX(command_mutex)
1977
1978typedef struct CommandEvent{
1979 Tcl_Event ev;
1980 Tcl_Interp* interp;
1981 char *name;
1982 int create;
1983 int *status;
1984 ClientData *data;
1985 Tcl_Condition done;
1986} CommandEvent;
1987
1988static int
1989Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001990{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001991 if (ev->create)
1992 *ev->status = Tcl_CreateCommand(
1993 ev->interp, ev->name, PythonCmd,
1994 ev->data, PythonCmdDelete) == NULL;
1995 else
1996 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
1997 Tcl_MutexLock(&command_mutex);
1998 Tcl_ConditionNotify(&ev->done);
1999 Tcl_MutexUnlock(&command_mutex);
2000 return 1;
2001}
2002
2003static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002004Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002005{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002006 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002007 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002008 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002009 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002010 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002011
Guido van Rossum43713e52000-02-29 13:59:29 +00002012 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002013 return NULL;
2014 if (!PyCallable_Check(func)) {
2015 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002016 return NULL;
2017 }
Guido van Rossum18468821994-06-20 07:49:28 +00002018
Martin v. Löwisa9656492003-03-30 08:44:58 +00002019#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002020 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002021 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002022 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002023#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002024
Guido van Rossum00d93061998-05-28 23:06:38 +00002025 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002026 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002027 return PyErr_NoMemory();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002028 Py_INCREF(self);
2029 Py_INCREF(func);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002030 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002031 data->func = func;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002032
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002033 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2034 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2035 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2036 ev->interp = self->interp;
2037 ev->create = 1;
2038 ev->name = cmdName;
2039 ev->data = (ClientData)data;
2040 ev->status = &err;
2041 ev->done = NULL;
2042 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
2043 }
2044 else {
2045 ENTER_TCL
2046 err = Tcl_CreateCommand(
2047 Tkapp_Interp(self), cmdName, PythonCmd,
2048 (ClientData)data, PythonCmdDelete) == NULL;
2049 LEAVE_TCL
2050 }
2051 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002052 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002053 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002054 return NULL;
2055 }
Guido van Rossum18468821994-06-20 07:49:28 +00002056
Barry Warsawfa701a81997-01-16 00:15:11 +00002057 Py_INCREF(Py_None);
2058 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002059}
2060
Barry Warsawfa701a81997-01-16 00:15:11 +00002061
2062
Guido van Rossum18468821994-06-20 07:49:28 +00002063static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002064Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002065{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002066 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002067 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002068 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002069
Guido van Rossum43713e52000-02-29 13:59:29 +00002070 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002071 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002072 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2073 CommandEvent *ev;
2074 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2075 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2076 ev->interp = self->interp;
2077 ev->create = 0;
2078 ev->name = cmdName;
2079 ev->status = &err;
2080 ev->done = NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002081 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done,
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002082 &command_mutex);
2083 }
2084 else {
2085 ENTER_TCL
2086 err = Tcl_DeleteCommand(self->interp, cmdName);
2087 LEAVE_TCL
2088 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002089 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002090 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2091 return NULL;
2092 }
2093 Py_INCREF(Py_None);
2094 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002095}
2096
Barry Warsawfa701a81997-01-16 00:15:11 +00002097
2098
Guido van Rossum00d93061998-05-28 23:06:38 +00002099#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002100/** File Handler **/
2101
Guido van Rossum00d93061998-05-28 23:06:38 +00002102typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002103 PyObject *func;
2104 PyObject *file;
2105 int id;
2106 struct _fhcdata *next;
2107} FileHandler_ClientData;
2108
2109static FileHandler_ClientData *HeadFHCD;
2110
2111static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002112NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002113{
2114 FileHandler_ClientData *p;
2115 p = PyMem_NEW(FileHandler_ClientData, 1);
2116 if (p != NULL) {
2117 Py_XINCREF(func);
2118 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002119 p->func = func;
2120 p->file = file;
2121 p->id = id;
2122 p->next = HeadFHCD;
2123 HeadFHCD = p;
2124 }
2125 return p;
2126}
2127
2128static void
Fred Drake509d79a2000-07-08 04:04:38 +00002129DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002130{
2131 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002132
2133 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002134 while ((p = *pp) != NULL) {
2135 if (p->id == id) {
2136 *pp = p->next;
2137 Py_XDECREF(p->func);
2138 Py_XDECREF(p->file);
2139 PyMem_DEL(p);
2140 }
2141 else
2142 pp = &p->next;
2143 }
2144}
2145
Guido van Rossuma597dde1995-01-10 20:56:29 +00002146static void
Fred Drake509d79a2000-07-08 04:04:38 +00002147FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002148{
Guido van Rossum00d93061998-05-28 23:06:38 +00002149 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002150 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002151
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002152 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002153 func = data->func;
2154 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002155
Barry Warsawfa701a81997-01-16 00:15:11 +00002156 arg = Py_BuildValue("(Oi)", file, (long) mask);
2157 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002158 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002159
2160 if (res == NULL) {
2161 errorInCmd = 1;
2162 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2163 }
2164 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002165 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002166}
2167
Guido van Rossum18468821994-06-20 07:49:28 +00002168static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002169Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2170 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002171{
Guido van Rossum00d93061998-05-28 23:06:38 +00002172 FileHandler_ClientData *data;
2173 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002174 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002175
Guido van Rossum2834b972000-10-06 16:58:26 +00002176 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2177 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002178 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002179
Martin v. Löwisa9656492003-03-30 08:44:58 +00002180#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002181 if (!self && !tcl_lock) {
2182 /* We don't have the Tcl lock since Tcl is threaded. */
2183 PyErr_SetString(PyExc_RuntimeError,
2184 "_tkinter.createfilehandler not supported "
2185 "for threaded Tcl");
2186 return NULL;
2187 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002188#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002189
2190 if (self) {
2191 CHECK_TCL_APPARTMENT;
2192 }
2193
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002194 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002195 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002196 return NULL;
2197 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002198 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002199 return NULL;
2200 }
2201
Guido van Rossuma80649b2000-03-28 20:07:05 +00002202 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002203 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002204 return NULL;
2205
Barry Warsawfa701a81997-01-16 00:15:11 +00002206 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002207 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002208 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002209 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002210 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002211 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002212}
2213
2214static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002215Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002216{
Barry Warsawfa701a81997-01-16 00:15:11 +00002217 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002218 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002219
Guido van Rossum43713e52000-02-29 13:59:29 +00002220 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002221 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002222
Martin v. Löwisa9656492003-03-30 08:44:58 +00002223#ifdef WITH_THREAD
Neal Norwitz12e22172003-03-03 21:16:39 +00002224 if (!self && !tcl_lock) {
2225 /* We don't have the Tcl lock since Tcl is threaded. */
2226 PyErr_SetString(PyExc_RuntimeError,
2227 "_tkinter.deletefilehandler not supported "
2228 "for threaded Tcl");
2229 return NULL;
2230 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002231#endif
Neal Norwitz12e22172003-03-03 21:16:39 +00002232
2233 if (self) {
2234 CHECK_TCL_APPARTMENT;
2235 }
2236
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002237 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002238 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002239 return NULL;
2240
Guido van Rossuma80649b2000-03-28 20:07:05 +00002241 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002242
Barry Warsawfa701a81997-01-16 00:15:11 +00002243 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002244 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002245 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002246 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002247 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002248 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002249}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002250#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002251
Barry Warsawfa701a81997-01-16 00:15:11 +00002252
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002253/**** Tktt Object (timer token) ****/
2254
Jeremy Hylton938ace62002-07-17 16:30:39 +00002255static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002256
Guido van Rossum00d93061998-05-28 23:06:38 +00002257typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002258 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002259 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002260 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002261} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002262
2263static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002264Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002265{
Barry Warsawfa701a81997-01-16 00:15:11 +00002266 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002267 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002268
Guido van Rossum43713e52000-02-29 13:59:29 +00002269 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002270 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002271 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002272 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002273 v->token = NULL;
2274 }
2275 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002276 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002277 Py_DECREF(func);
2278 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002279 }
2280 Py_INCREF(Py_None);
2281 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002282}
2283
2284static PyMethodDef Tktt_methods[] =
2285{
Neal Norwitzb0493252002-03-31 14:44:22 +00002286 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002287 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002288};
2289
2290static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002291Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002292{
Barry Warsawfa701a81997-01-16 00:15:11 +00002293 TkttObject *v;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002294
Guido van Rossumb18618d2000-05-03 23:44:39 +00002295 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002296 if (v == NULL)
2297 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002298
Guido van Rossum00d93061998-05-28 23:06:38 +00002299 Py_INCREF(func);
2300 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002301 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002302
2303 /* Extra reference, deleted when called or when handler is deleted */
2304 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002305 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002306}
2307
2308static void
Fred Drake509d79a2000-07-08 04:04:38 +00002309Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002310{
Guido van Rossum00d93061998-05-28 23:06:38 +00002311 TkttObject *v = (TkttObject *)self;
2312 PyObject *func = v->func;
2313
2314 Py_XDECREF(func);
2315
Guido van Rossumb18618d2000-05-03 23:44:39 +00002316 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002317}
2318
Guido van Rossum597ac201998-05-12 14:36:19 +00002319static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002320Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002321{
Barry Warsawfa701a81997-01-16 00:15:11 +00002322 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002323 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002324
Tim Peters885d4572001-11-28 20:27:42 +00002325 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002326 v->func == NULL ? ", handler deleted" : "");
Walter Dörwald1ab83302007-05-18 17:15:44 +00002327 return PyUnicode_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002328}
2329
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002330static PyTypeObject Tktt_Type =
2331{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002332 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002333 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002334 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002335 0, /*tp_itemsize */
2336 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002337 0, /*tp_print */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002338 0, /*tp_getattr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002339 0, /*tp_setattr */
2340 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00002341 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002342 0, /*tp_as_number */
2343 0, /*tp_as_sequence */
2344 0, /*tp_as_mapping */
2345 0, /*tp_hash */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002346 0, /*tp_call*/
2347 0, /*tp_str*/
2348 0, /*tp_getattro*/
2349 0, /*tp_setattro*/
2350 0, /*tp_as_buffer*/
2351 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2352 0, /*tp_doc*/
2353 0, /*tp_traverse*/
2354 0, /*tp_clear*/
2355 0, /*tp_richcompare*/
2356 0, /*tp_weaklistoffset*/
2357 0, /*tp_iter*/
2358 0, /*tp_iternext*/
2359 Tktt_methods, /*tp_methods*/
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002360};
2361
Barry Warsawfa701a81997-01-16 00:15:11 +00002362
2363
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002364/** Timer Handler **/
2365
2366static void
Fred Drake509d79a2000-07-08 04:04:38 +00002367TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002368{
Guido van Rossum00d93061998-05-28 23:06:38 +00002369 TkttObject *v = (TkttObject *)clientData;
2370 PyObject *func = v->func;
2371 PyObject *res;
2372
2373 if (func == NULL)
2374 return;
2375
2376 v->func = NULL;
2377
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002378 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002379
2380 res = PyEval_CallObject(func, NULL);
2381 Py_DECREF(func);
2382 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002383
Barry Warsawfa701a81997-01-16 00:15:11 +00002384 if (res == NULL) {
2385 errorInCmd = 1;
2386 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2387 }
2388 else
2389 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002390
2391 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002392}
2393
2394static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002395Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002396{
Barry Warsawfa701a81997-01-16 00:15:11 +00002397 int milliseconds;
2398 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002399 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002400
Guido van Rossum2834b972000-10-06 16:58:26 +00002401 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2402 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002403 return NULL;
2404 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002405 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002406 return NULL;
2407 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002408
Martin v. Löwisa9656492003-03-30 08:44:58 +00002409#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002410 if (!self && !tcl_lock) {
2411 /* We don't have the Tcl lock since Tcl is threaded. */
2412 PyErr_SetString(PyExc_RuntimeError,
2413 "_tkinter.createtimerhandler not supported "
2414 "for threaded Tcl");
2415 return NULL;
2416 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002417#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002418
2419 if (self) {
2420 CHECK_TCL_APPARTMENT;
2421 }
2422
Guido van Rossum00d93061998-05-28 23:06:38 +00002423 v = Tktt_New(func);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002424 if (v) {
2425 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2426 (ClientData)v);
2427 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002428
Guido van Rossum00d93061998-05-28 23:06:38 +00002429 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002430}
2431
Barry Warsawfa701a81997-01-16 00:15:11 +00002432
Guido van Rossum18468821994-06-20 07:49:28 +00002433/** Event Loop **/
2434
Guido van Rossum18468821994-06-20 07:49:28 +00002435static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002436Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002437{
Barry Warsawfa701a81997-01-16 00:15:11 +00002438 int threshold = 0;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002439 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002440#ifdef WITH_THREAD
2441 PyThreadState *tstate = PyThreadState_Get();
2442#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002443
Guido van Rossum43713e52000-02-29 13:59:29 +00002444 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002445 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002446
Martin v. Löwisa9656492003-03-30 08:44:58 +00002447#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002448 if (!self && !tcl_lock) {
2449 /* We don't have the Tcl lock since Tcl is threaded. */
2450 PyErr_SetString(PyExc_RuntimeError,
2451 "_tkinter.mainloop not supported "
2452 "for threaded Tcl");
2453 return NULL;
2454 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002455#endif
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002456
2457 if (self) {
2458 CHECK_TCL_APPARTMENT;
2459 self->dispatching = 1;
2460 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002461
Barry Warsawfa701a81997-01-16 00:15:11 +00002462 quitMainLoop = 0;
2463 while (Tk_GetNumMainWindows() > threshold &&
2464 !quitMainLoop &&
2465 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002466 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002467 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002468
2469#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002470 if (self && self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002471 /* Allow other Python threads to run. */
2472 ENTER_TCL
2473 result = Tcl_DoOneEvent(0);
2474 LEAVE_TCL
2475 }
2476 else {
2477 Py_BEGIN_ALLOW_THREADS
2478 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2479 tcl_tstate = tstate;
2480 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2481 tcl_tstate = NULL;
2482 if(tcl_lock)PyThread_release_lock(tcl_lock);
2483 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002484 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002485 Py_END_ALLOW_THREADS
2486 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002487#else
2488 result = Tcl_DoOneEvent(0);
2489#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002490
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002491 if (PyErr_CheckSignals() != 0) {
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002492 if (self)
2493 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002494 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002495 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002496 if (result < 0)
2497 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002498 }
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002499 if (self)
2500 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002501 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002502
Barry Warsawfa701a81997-01-16 00:15:11 +00002503 if (errorInCmd) {
2504 errorInCmd = 0;
2505 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2506 excInCmd = valInCmd = trbInCmd = NULL;
2507 return NULL;
2508 }
2509 Py_INCREF(Py_None);
2510 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002511}
2512
2513static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002514Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002515{
Guido van Rossum35d43371997-08-02 00:09:09 +00002516 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002517 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002518
Guido van Rossum43713e52000-02-29 13:59:29 +00002519 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002520 return NULL;
2521
Guido van Rossum00d93061998-05-28 23:06:38 +00002522 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002523 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002524 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002525 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002526}
2527
2528static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002529Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002530{
2531
Guido van Rossum43713e52000-02-29 13:59:29 +00002532 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002533 return NULL;
2534
2535 quitMainLoop = 1;
2536 Py_INCREF(Py_None);
2537 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002538}
2539
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002540static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002541Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002542{
2543
Guido van Rossum43713e52000-02-29 13:59:29 +00002544 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002545 return NULL;
2546
Christian Heimes217cfd12007-12-02 14:31:20 +00002547 return PyLong_FromLong((long)Tkapp_Interp(self));
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002548}
2549
David Aschere2b4b322004-02-18 05:59:53 +00002550static PyObject *
2551Tkapp_TkInit(PyObject *self, PyObject *args)
2552{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002553 static int has_failed;
David Aschere2b4b322004-02-18 05:59:53 +00002554 Tcl_Interp *interp = Tkapp_Interp(self);
Neal Norwitz44dbae82004-02-19 02:44:22 +00002555 Tk_Window main_window;
David Aschere2b4b322004-02-18 05:59:53 +00002556 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002557 int err;
Neal Norwitz44dbae82004-02-19 02:44:22 +00002558 main_window = Tk_MainWindow(interp);
David Aschere2b4b322004-02-18 05:59:53 +00002559
Thomas Wouters477c8d52006-05-27 19:21:47 +00002560 /* In all current versions of Tk (including 8.4.13), Tk_Init
2561 deadlocks on the second call when the first call failed.
2562 To avoid the deadlock, we just refuse the second call through
2563 a static variable. */
2564 if (has_failed) {
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002565 PyErr_SetString(Tkinter_TclError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002566 "Calling Tk_Init again after a previous call failed might deadlock");
2567 return NULL;
2568 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002569
David Aschere2b4b322004-02-18 05:59:53 +00002570 /* We want to guard against calling Tk_Init() multiple times */
2571 CHECK_TCL_APPARTMENT;
2572 ENTER_TCL
2573 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2574 ENTER_OVERLAP
2575 if (err == TCL_ERROR) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002576 /* This sets an exception, but we cannot return right
2577 away because we need to exit the overlap first. */
2578 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002579 } else {
2580 _tk_exists = Tkapp_Result(self);
2581 }
2582 LEAVE_OVERLAP_TCL
2583 if (err == TCL_ERROR) {
2584 return NULL;
2585 }
2586 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2587 if (Tk_Init(interp) == TCL_ERROR) {
2588 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
Thomas Wouters477c8d52006-05-27 19:21:47 +00002589 has_failed = 1;
David Aschere2b4b322004-02-18 05:59:53 +00002590 return NULL;
2591 }
2592 }
2593 Py_INCREF(Py_None);
2594 return Py_None;
2595}
Barry Warsawfa701a81997-01-16 00:15:11 +00002596
Martin v. Löwisffad6332002-11-26 09:28:05 +00002597static PyObject *
2598Tkapp_WantObjects(PyObject *self, PyObject *args)
2599{
2600
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002601 int wantobjects = -1;
2602 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002603 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002604 if (wantobjects == -1)
2605 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002606 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002607
2608 Py_INCREF(Py_None);
2609 return Py_None;
2610}
2611
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002612static PyObject *
2613Tkapp_WillDispatch(PyObject *self, PyObject *args)
2614{
2615
2616 ((TkappObject*)self)->dispatching = 1;
2617
2618 Py_INCREF(Py_None);
2619 return Py_None;
2620}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002621
Barry Warsawfa701a81997-01-16 00:15:11 +00002622
Guido van Rossum18468821994-06-20 07:49:28 +00002623/**** Tkapp Method List ****/
2624
2625static PyMethodDef Tkapp_methods[] =
2626{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002627 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002628 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002629 {"call", Tkapp_Call, METH_VARARGS},
2630 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002631 {"eval", Tkapp_Eval, METH_VARARGS},
2632 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2633 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2634 {"record", Tkapp_Record, METH_VARARGS},
2635 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2636 {"setvar", Tkapp_SetVar, METH_VARARGS},
2637 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2638 {"getvar", Tkapp_GetVar, METH_VARARGS},
2639 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2640 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2641 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2642 {"getint", Tkapp_GetInt, METH_VARARGS},
2643 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2644 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2645 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2646 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2647 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2648 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2649 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2650 {"split", Tkapp_Split, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002651 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002652 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2653 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002654#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002655 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2656 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002657#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002658 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2659 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2660 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2661 {"quit", Tkapp_Quit, METH_VARARGS},
2662 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002663 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002664 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002665};
2666
Barry Warsawfa701a81997-01-16 00:15:11 +00002667
2668
Guido van Rossum18468821994-06-20 07:49:28 +00002669/**** Tkapp Type Methods ****/
2670
2671static void
Fred Drake509d79a2000-07-08 04:04:38 +00002672Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002673{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002674 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002675 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002676 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002677 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002678 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002679 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002680}
2681
Guido van Rossum18468821994-06-20 07:49:28 +00002682static PyTypeObject Tkapp_Type =
2683{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002684 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002685 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002686 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002687 0, /*tp_itemsize */
2688 Tkapp_Dealloc, /*tp_dealloc */
2689 0, /*tp_print */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002690 0, /*tp_getattr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002691 0, /*tp_setattr */
2692 0, /*tp_compare */
2693 0, /*tp_repr */
2694 0, /*tp_as_number */
2695 0, /*tp_as_sequence */
2696 0, /*tp_as_mapping */
2697 0, /*tp_hash */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002698 0, /*tp_call*/
2699 0, /*tp_str*/
2700 0, /*tp_getattro*/
2701 0, /*tp_setattro*/
2702 0, /*tp_as_buffer*/
2703 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2704 0, /*tp_doc*/
2705 0, /*tp_traverse*/
2706 0, /*tp_clear*/
2707 0, /*tp_richcompare*/
2708 0, /*tp_weaklistoffset*/
2709 0, /*tp_iter*/
2710 0, /*tp_iternext*/
2711 Tkapp_methods, /*tp_methods*/
Guido van Rossum18468821994-06-20 07:49:28 +00002712};
2713
Barry Warsawfa701a81997-01-16 00:15:11 +00002714
2715
Guido van Rossum18468821994-06-20 07:49:28 +00002716/**** Tkinter Module ****/
2717
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002718typedef struct {
2719 PyObject* tuple;
2720 int size; /* current size */
2721 int maxsize; /* allocated size */
2722} FlattenContext;
2723
2724static int
2725_bump(FlattenContext* context, int size)
2726{
Guido van Rossum2834b972000-10-06 16:58:26 +00002727 /* expand tuple to hold (at least) size new items.
2728 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002729
2730 int maxsize = context->maxsize * 2;
2731
2732 if (maxsize < context->size + size)
2733 maxsize = context->size + size;
2734
2735 context->maxsize = maxsize;
2736
Tim Peters4324aa32001-05-28 22:30:08 +00002737 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002738}
2739
2740static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002741_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002742{
2743 /* add tuple or list to argument tuple (recursively) */
2744
2745 int i, size;
2746
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002747 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002748 PyErr_SetString(PyExc_ValueError,
2749 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002750 return 0;
2751 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002752 size = PyList_GET_SIZE(item);
2753 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002754 if (context->size + size > context->maxsize &&
2755 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002756 return 0;
2757 /* copy items to output tuple */
2758 for (i = 0; i < size; i++) {
2759 PyObject *o = PyList_GET_ITEM(item, i);
2760 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002761 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002762 return 0;
2763 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002764 if (context->size + 1 > context->maxsize &&
2765 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002766 return 0;
2767 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002768 PyTuple_SET_ITEM(context->tuple,
2769 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002770 }
2771 }
2772 } else if (PyTuple_Check(item)) {
2773 /* same, for tuples */
2774 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002775 if (context->size + size > context->maxsize &&
2776 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002777 return 0;
2778 for (i = 0; i < size; i++) {
2779 PyObject *o = PyTuple_GET_ITEM(item, i);
2780 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002781 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002782 return 0;
2783 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002784 if (context->size + 1 > context->maxsize &&
2785 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002786 return 0;
2787 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002788 PyTuple_SET_ITEM(context->tuple,
2789 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002790 }
2791 }
2792 } else {
2793 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2794 return 0;
2795 }
2796 return 1;
2797}
2798
2799static PyObject *
2800Tkinter_Flatten(PyObject* self, PyObject* args)
2801{
2802 FlattenContext context;
2803 PyObject* item;
2804
2805 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2806 return NULL;
2807
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002808 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002809 if (context.maxsize <= 0)
2810 return PyTuple_New(0);
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002811
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002812 context.tuple = PyTuple_New(context.maxsize);
2813 if (!context.tuple)
2814 return NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002815
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002816 context.size = 0;
2817
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002818 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002819 return NULL;
2820
Tim Peters4324aa32001-05-28 22:30:08 +00002821 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002822 return NULL;
2823
2824 return context.tuple;
2825}
2826
Guido van Rossum18468821994-06-20 07:49:28 +00002827static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002828Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002829{
Barry Warsawfa701a81997-01-16 00:15:11 +00002830 char *screenName = NULL;
Martin v. Löwisb9279bc2008-04-05 19:47:23 +00002831 char *baseName = NULL; /* XXX this is not used anymore;
2832 try getting rid of it. */
Barry Warsawfa701a81997-01-16 00:15:11 +00002833 char *className = NULL;
2834 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002835 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002836 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002837 int sync = 0; /* pass -sync to wish */
2838 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002839
Barry Warsawfa701a81997-01-16 00:15:11 +00002840 className = "Tk";
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002841
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002842 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002843 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002844 &interactive, &wantobjects, &wantTk,
2845 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00002846 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002847
Martin v. Löwisb9279bc2008-04-05 19:47:23 +00002848 return (PyObject *) Tkapp_New(screenName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002849 interactive, wantobjects, wantTk,
2850 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002851}
2852
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002853static PyObject *
2854Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2855{
2856 int new_val;
2857 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2858 return NULL;
2859 if (new_val < 0) {
2860 PyErr_SetString(PyExc_ValueError,
2861 "busywaitinterval must be >= 0");
2862 return NULL;
2863 }
2864 Tkinter_busywaitinterval = new_val;
2865 Py_INCREF(Py_None);
2866 return Py_None;
2867}
2868
2869static char setbusywaitinterval_doc[] =
2870"setbusywaitinterval(n) -> None\n\
2871\n\
2872Set the busy-wait interval in milliseconds between successive\n\
2873calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2874It should be set to a divisor of the maximum time between\n\
2875frames in an animation.";
2876
2877static PyObject *
2878Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2879{
Christian Heimes217cfd12007-12-02 14:31:20 +00002880 return PyLong_FromLong(Tkinter_busywaitinterval);
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002881}
2882
2883static char getbusywaitinterval_doc[] =
2884"getbusywaitinterval() -> int\n\
2885\n\
2886Return the current busy-wait interval between successive\n\
2887calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2888
Guido van Rossum18468821994-06-20 07:49:28 +00002889static PyMethodDef moduleMethods[] =
2890{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002891 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2892 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002893#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002894 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2895 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002896#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002897 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2898 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2899 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2900 {"quit", Tkapp_Quit, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002901 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2902 setbusywaitinterval_doc},
2903 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2904 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00002905 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002906};
2907
Guido van Rossum7bf15641998-05-22 18:28:17 +00002908#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002909
2910static int stdin_ready = 0;
2911
Guido van Rossumad4db171998-06-13 13:56:28 +00002912#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002913static void
Fred Drake509d79a2000-07-08 04:04:38 +00002914MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002915{
2916 stdin_ready = 1;
2917}
Guido van Rossumad4db171998-06-13 13:56:28 +00002918#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002919
Martin v. Löwisa9656492003-03-30 08:44:58 +00002920#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002921static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002922#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002923
Guido van Rossum18468821994-06-20 07:49:28 +00002924static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002925EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002926{
Guido van Rossumad4db171998-06-13 13:56:28 +00002927#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002928 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002929#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002930#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002931 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002932#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002933 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002934 errorInCmd = 0;
2935#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002936 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002937 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002938#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002939 while (!errorInCmd && !stdin_ready) {
2940 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002941#ifdef MS_WINDOWS
2942 if (_kbhit()) {
2943 stdin_ready = 1;
2944 break;
2945 }
2946#endif
2947#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002948 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002949 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002950 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002951
Guido van Rossum00d93061998-05-28 23:06:38 +00002952 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002953
2954 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002955 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002956 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002957 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00002958 Py_END_ALLOW_THREADS
2959#else
2960 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002961#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002962
2963 if (result < 0)
2964 break;
2965 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002966#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002967 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002968#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002969 if (errorInCmd) {
2970 errorInCmd = 0;
2971 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2972 excInCmd = valInCmd = trbInCmd = NULL;
2973 PyErr_Print();
2974 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002975#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002976 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002977#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002978 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002979}
Guido van Rossum18468821994-06-20 07:49:28 +00002980
Guido van Rossum00d93061998-05-28 23:06:38 +00002981#endif
2982
Guido van Rossum7bf15641998-05-22 18:28:17 +00002983static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002984EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002985{
Guido van Rossum00d93061998-05-28 23:06:38 +00002986#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002987 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002988#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002989 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002990#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002991 PyOS_InputHook = EventHook;
2992 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002993#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002994}
2995
2996static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002997DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002998{
Guido van Rossum00d93061998-05-28 23:06:38 +00002999#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003000 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3001 PyOS_InputHook = NULL;
3002 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003003#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003004}
3005
Barry Warsawfa701a81997-01-16 00:15:11 +00003006
3007/* all errors will be checked in one fell swoop in init_tkinter() */
3008static void
Fred Drake509d79a2000-07-08 04:04:38 +00003009ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003010{
Christian Heimes217cfd12007-12-02 14:31:20 +00003011 PyObject *v = PyLong_FromLong(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003012 if (v) {
3013 PyDict_SetItemString(d, name, v);
3014 Py_DECREF(v);
3015 }
3016}
3017static void
Fred Drake509d79a2000-07-08 04:04:38 +00003018ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003019{
Martin v. Löwis4040fb82007-08-13 06:01:43 +00003020 PyObject *v = PyUnicode_FromString(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003021 if (v) {
3022 PyDict_SetItemString(d, name, v);
3023 Py_DECREF(v);
3024 }
3025}
3026
3027
Martin v. Löwis1a214512008-06-11 05:26:20 +00003028static struct PyModuleDef _tkintermodule = {
3029 PyModuleDef_HEAD_INIT,
3030 "_tkinter",
3031 NULL,
3032 -1,
3033 moduleMethods,
3034 NULL,
3035 NULL,
3036 NULL,
3037 NULL
3038};
3039
Mark Hammond62b1ab12002-07-23 06:31:15 +00003040PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00003041PyInit__tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003042{
Martin v. Löwis790465f2008-04-05 20:41:37 +00003043 PyObject *m, *d, *uexe, *cexe;
Guido van Rossum18468821994-06-20 07:49:28 +00003044
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00003045 if (PyType_Ready(&Tkapp_Type) < 0)
3046 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00003047
3048#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003049 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003050#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003051
Martin v. Löwis1a214512008-06-11 05:26:20 +00003052 m = PyModule_Create(&_tkintermodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003053 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00003054 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00003055
Barry Warsawfa701a81997-01-16 00:15:11 +00003056 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003057 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003058 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003059
Guido van Rossum35d43371997-08-02 00:09:09 +00003060 ins_long(d, "READABLE", TCL_READABLE);
3061 ins_long(d, "WRITABLE", TCL_WRITABLE);
3062 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3063 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3064 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3065 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3066 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3067 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3068 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003069 ins_string(d, "TK_VERSION", TK_VERSION);
3070 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003071
Guido van Rossum83551bf1997-09-13 00:44:23 +00003072 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003073
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00003074 if (PyType_Ready(&Tktt_Type) < 0)
3075 return NULL;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003076 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3077
Christian Heimes90aa7642007-12-19 02:45:37 +00003078 Py_TYPE(&PyTclObject_Type) = &PyType_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003079 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003080
3081#ifdef TK_AQUA
3082 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3083 * start waking up. Note that Tcl_FindExecutable will do this, this
3084 * code must be above it! The original warning from
3085 * tkMacOSXAppInit.c is copied below.
3086 *
3087 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3088 * Tcl interpreter for now. It probably should work to do this
3089 * in the other order, but for now it doesn't seem to.
3090 *
3091 */
3092 Tk_MacOSXSetupTkNotifier();
3093#endif
3094
3095
Guido van Rossume187b0e2000-03-27 21:46:29 +00003096 /* This helps the dynamic loader; in Unicode aware Tcl versions
3097 it also helps Tcl find its encodings. */
Martin v. Löwis790465f2008-04-05 20:41:37 +00003098 uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1);
3099 if (uexe) {
3100 cexe = PyUnicode_AsEncodedString(uexe,
3101 Py_FileSystemDefaultEncoding,
3102 NULL);
3103 if (cexe)
Christian Heimes72b710a2008-05-26 13:28:38 +00003104 Tcl_FindExecutable(PyBytes_AsString(cexe));
Martin v. Löwis790465f2008-04-05 20:41:37 +00003105 Py_XDECREF(cexe);
3106 Py_DECREF(uexe);
3107 }
Guido van Rossume187b0e2000-03-27 21:46:29 +00003108
Martin v. Löwis1a214512008-06-11 05:26:20 +00003109 if (PyErr_Occurred()) {
3110 Py_DECREF(m);
3111 return NULL;
3112 }
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003113
Guido van Rossum43ff8681998-07-14 18:02:13 +00003114#if 0
3115 /* This was not a good idea; through <Destroy> bindings,
3116 Tcl_Finalize() may invoke Python code but at that point the
3117 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003118 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003119#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +00003120 return m;
Guido van Rossum18468821994-06-20 07:49:28 +00003121}