blob: ea36297c382c977848c94c592946827bc120a43b [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
Guilherme Polo363161a2009-02-06 22:48:07 +000012 Only Tcl/Tk 8.3.1 and later are supported. Older versions are not
13 supported. Use Python 2.6 or older if you cannot upgrade your
14 Tcl/Tk libraries.
Guido van Rossuma80649b2000-03-28 20:07:05 +000015*/
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
47#define PyBool_FromLong PyInt_FromLong
48#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
Guilherme Polo5d64c332009-04-05 02:11:19 +000070#include "tkinter.h"
71
Jason Tishlerbbe89612002-12-31 20:30:46 +000072/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
Martin v. Löwis5b177f12002-12-30 18:14:15 +000073#ifndef CONST84_RETURN
74#define CONST84_RETURN
Jason Tishlerbbe89612002-12-31 20:30:46 +000075#undef CONST
Martin v. Löwis5b177f12002-12-30 18:14:15 +000076#define CONST
77#endif
78
Guilherme Poloc5eba1e2009-02-09 20:57:45 +000079#if TK_VERSION_HEX < 0x08030102
80#error "Tk older than 8.3.1 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
Martin v. Löwis6f29ff32003-04-16 20:34:55 +000086 either UTF-16 or UCS-4.
87 Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for
88 Tcl_Unichar. This is also ok as long as Python uses UCS-4,
89 as well.
90*/
91#if TCL_UTF_MAX != 3 && !(defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==6)
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 Heimese93237d2007-12-19 02:37:44 +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 Heimese93237d2007-12-19 02:37:44 +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
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000283#ifdef TKINTER_PROTECT_LOADTK
284static int tk_load_failed;
285#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000286
287
Guido van Rossum18468821994-06-20 07:49:28 +0000288static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000289Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000290{
Barry Warsawfa701a81997-01-16 00:15:11 +0000291 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
292 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000293}
294
Barry Warsawfa701a81997-01-16 00:15:11 +0000295
Barry Warsawfa701a81997-01-16 00:15:11 +0000296
Guido van Rossum18468821994-06-20 07:49:28 +0000297/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000298
Martin v. Löwis28e9ce92003-05-09 08:19:48 +0000299static int Tkinter_busywaitinterval = 20;
300
Guido van Rossum00d93061998-05-28 23:06:38 +0000301#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000302#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000303
Guido van Rossum00d93061998-05-28 23:06:38 +0000304/* Millisecond sleep() for Unix platforms. */
305
306static void
Fred Drake509d79a2000-07-08 04:04:38 +0000307Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000308{
309 /* XXX Too bad if you don't have select(). */
310 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000311 t.tv_sec = milli/1000;
312 t.tv_usec = (milli%1000) * 1000;
313 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
314}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000315#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000316
Martin v. Löwis5b26abb2002-12-28 09:23:09 +0000317/* Wait up to 1s for the mainloop to come up. */
318
319static int
320WaitForMainloop(TkappObject* self)
321{
322 int i;
323 for (i = 0; i < 10; i++) {
324 if (self->dispatching)
325 return 1;
326 Py_BEGIN_ALLOW_THREADS
327 Sleep(100);
328 Py_END_ALLOW_THREADS
329 }
330 if (self->dispatching)
331 return 1;
332 PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
333 return 0;
334}
Martin v. Löwisa9656492003-03-30 08:44:58 +0000335#endif /* WITH_THREAD */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000336
Guido van Rossum00d93061998-05-28 23:06:38 +0000337
Guido van Rossum18468821994-06-20 07:49:28 +0000338static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000339AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000340{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000341 if (PyString_Check(value))
342 return PyString_AsString(value);
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000343#ifdef Py_USING_UNICODE
Guido van Rossum2834b972000-10-06 16:58:26 +0000344 else if (PyUnicode_Check(value)) {
345 PyObject *v = PyUnicode_AsUTF8String(value);
346 if (v == NULL)
347 return NULL;
348 if (PyList_Append(tmp, v) != 0) {
349 Py_DECREF(v);
350 return NULL;
351 }
352 Py_DECREF(v);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000353 return PyString_AsString(v);
Guido van Rossum2834b972000-10-06 16:58:26 +0000354 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000355#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000356 else {
357 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000358 if (v == NULL)
359 return NULL;
360 if (PyList_Append(tmp, v) != 0) {
361 Py_DECREF(v);
362 return NULL;
363 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000364 Py_DECREF(v);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000365 return PyString_AsString(v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000366 }
Guido van Rossum18468821994-06-20 07:49:28 +0000367}
368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369
370
Guido van Rossum18468821994-06-20 07:49:28 +0000371#define ARGSZ 64
372
373static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000374Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000375{
Barry Warsawfa701a81997-01-16 00:15:11 +0000376 PyObject *tmp = NULL;
377 char *argvStore[ARGSZ];
378 char **argv = NULL;
379 int fvStore[ARGSZ];
380 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000381 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000382 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 if (!(tmp = PyList_New(0)))
385 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000386
Barry Warsawfa701a81997-01-16 00:15:11 +0000387 argv = argvStore;
388 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000389
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 if (args == NULL)
391 argc = 0;
392
393 else if (!PyTuple_Check(args)) {
394 argc = 1;
395 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000396 if (!(argv[0] = AsString(args, tmp)))
397 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000398 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000399 else {
400 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000401
Barry Warsawfa701a81997-01-16 00:15:11 +0000402 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000403 argv = (char **)ckalloc(argc * sizeof(char *));
404 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000405 if (argv == NULL || fv == NULL) {
406 PyErr_NoMemory();
407 goto finally;
408 }
409 }
410
411 for (i = 0; i < argc; i++) {
412 PyObject *v = PyTuple_GetItem(args, i);
413 if (PyTuple_Check(v)) {
414 fv[i] = 1;
415 if (!(argv[i] = Merge(v)))
416 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000417 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000418 }
419 else if (v == Py_None) {
420 argc = i;
421 break;
422 }
423 else {
424 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000425 if (!(argv[i] = AsString(v, tmp)))
426 goto finally;
427 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 }
429 }
Guido van Rossum18468821994-06-20 07:49:28 +0000430 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000432 if (res == NULL)
433 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000434
Barry Warsawfa701a81997-01-16 00:15:11 +0000435 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000436 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000437 if (fv[i]) {
438 ckfree(argv[i]);
439 }
440 if (argv != argvStore)
441 ckfree(FREECAST argv);
442 if (fv != fvStore)
443 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000444
Barry Warsawfa701a81997-01-16 00:15:11 +0000445 Py_DECREF(tmp);
446 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000447}
448
Barry Warsawfa701a81997-01-16 00:15:11 +0000449
450
Guido van Rossum18468821994-06-20 07:49:28 +0000451static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000452Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000453{
Barry Warsawfa701a81997-01-16 00:15:11 +0000454 int argc;
455 char **argv;
456 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000457
Barry Warsawfa701a81997-01-16 00:15:11 +0000458 if (list == NULL) {
459 Py_INCREF(Py_None);
460 return Py_None;
461 }
Guido van Rossum18468821994-06-20 07:49:28 +0000462
Guido van Rossum00d93061998-05-28 23:06:38 +0000463 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000464 /* Not a list.
465 * Could be a quoted string containing funnies, e.g. {"}.
466 * Return the string itself.
467 */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000468 return PyString_FromString(list);
Barry Warsawfa701a81997-01-16 00:15:11 +0000469 }
Guido van Rossum18468821994-06-20 07:49:28 +0000470
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 if (argc == 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000472 v = PyString_FromString("");
Barry Warsawfa701a81997-01-16 00:15:11 +0000473 else if (argc == 1)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000474 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000475 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 int i;
477 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000478
Barry Warsawfa701a81997-01-16 00:15:11 +0000479 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000480 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000481 Py_DECREF(v);
482 v = NULL;
483 break;
484 }
485 PyTuple_SetItem(v, i, w);
486 }
487 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000488 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000489 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000490}
491
Martin v. Löwisffad6332002-11-26 09:28:05 +0000492/* In some cases, Tcl will still return strings that are supposed to be
493 lists. SplitObj walks through a nested tuple, finding string objects that
494 need to be split. */
495
Martin v. Löwis111c1802008-06-13 07:47:47 +0000496static PyObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000497SplitObj(PyObject *arg)
498{
499 if (PyTuple_Check(arg)) {
500 int i, size;
501 PyObject *elem, *newelem, *result;
502
503 size = PyTuple_Size(arg);
504 result = NULL;
505 /* Recursively invoke SplitObj for all tuple items.
506 If this does not return a new object, no action is
507 needed. */
508 for(i = 0; i < size; i++) {
509 elem = PyTuple_GetItem(arg, i);
510 newelem = SplitObj(elem);
511 if (!newelem) {
512 Py_XDECREF(result);
513 return NULL;
514 }
515 if (!result) {
516 int k;
517 if (newelem == elem) {
518 Py_DECREF(newelem);
519 continue;
520 }
521 result = PyTuple_New(size);
522 if (!result)
523 return NULL;
524 for(k = 0; k < i; k++) {
525 elem = PyTuple_GetItem(arg, k);
526 Py_INCREF(elem);
527 PyTuple_SetItem(result, k, elem);
528 }
529 }
530 PyTuple_SetItem(result, i, newelem);
531 }
532 if (result)
533 return result;
534 /* Fall through, returning arg. */
535 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000536 else if (PyString_Check(arg)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000537 int argc;
538 char **argv;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000539 char *list = PyString_AsString(arg);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000540
541 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
542 Py_INCREF(arg);
543 return arg;
544 }
545 Tcl_Free(FREECAST argv);
546 if (argc > 1)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000547 return Split(PyString_AsString(arg));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000548 /* Fall through, returning arg. */
549 }
550 Py_INCREF(arg);
551 return arg;
552}
Barry Warsawfa701a81997-01-16 00:15:11 +0000553
554
Guido van Rossum18468821994-06-20 07:49:28 +0000555/**** Tkapp Object ****/
556
557#ifndef WITH_APPINIT
558int
Fred Drake509d79a2000-07-08 04:04:38 +0000559Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000560{
David Aschere2b4b322004-02-18 05:59:53 +0000561 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000562
Barry Warsawfa701a81997-01-16 00:15:11 +0000563 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000564 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000565 return TCL_ERROR;
566 }
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000567
568 _tkinter_skip_tk_init = Tcl_GetVar(interp,
569 "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
570 if (_tkinter_skip_tk_init != NULL &&
571 strcmp(_tkinter_skip_tk_init, "1") == 0) {
572 return TCL_OK;
Barry Warsawfa701a81997-01-16 00:15:11 +0000573 }
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000574
575#ifdef TKINTER_PROTECT_LOADTK
576 if (tk_load_failed) {
577 PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG);
578 return TCL_ERROR;
579 }
580#endif
581
582 if (Tk_Init(interp) == TCL_ERROR) {
583#ifdef TKINTER_PROTECT_LOADTK
584 tk_load_failed = 1;
585#endif
586 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
587 return TCL_ERROR;
588 }
589
Barry Warsawfa701a81997-01-16 00:15:11 +0000590 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000591}
592#endif /* !WITH_APPINIT */
593
Guido van Rossum18468821994-06-20 07:49:28 +0000594
Barry Warsawfa701a81997-01-16 00:15:11 +0000595
596
597/* Initialize the Tk application; see the `main' function in
598 * `tkMain.c'.
599 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000600
Thomas Wouters58d05102000-07-24 14:43:35 +0000601static void EnableEventHook(void); /* Forward */
602static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000603
Barry Warsawfa701a81997-01-16 00:15:11 +0000604static TkappObject *
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000605Tkapp_New(char *screenName, char *baseName, char *className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000606 int interactive, int wantobjects, int wantTk, int sync, char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000607{
608 TkappObject *v;
609 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000610
Guido van Rossumb18618d2000-05-03 23:44:39 +0000611 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000612 if (v == NULL)
613 return NULL;
614
615 v->interp = Tcl_CreateInterp();
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000616 v->wantobjects = wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000617 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
618 TCL_GLOBAL_ONLY) != NULL;
619 v->thread_id = Tcl_GetCurrentThread();
620 v->dispatching = 0;
621
622#ifndef TCL_THREADS
623 if (v->threaded) {
624 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
625 Py_DECREF(v);
626 return 0;
627 }
628#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000629#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000630 if (v->threaded && tcl_lock) {
631 /* If Tcl is threaded, we don't need the lock. */
632 PyThread_free_lock(tcl_lock);
633 tcl_lock = NULL;
634 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000635#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000636
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000637 v->BooleanType = Tcl_GetObjType("boolean");
638 v->ByteArrayType = Tcl_GetObjType("bytearray");
639 v->DoubleType = Tcl_GetObjType("double");
640 v->IntType = Tcl_GetObjType("int");
641 v->ListType = Tcl_GetObjType("list");
642 v->ProcBodyType = Tcl_GetObjType("procbody");
643 v->StringType = Tcl_GetObjType("string");
644
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000645 /* Delete the 'exit' command, which can screw things up */
646 Tcl_DeleteCommand(v->interp, "exit");
647
Barry Warsawfa701a81997-01-16 00:15:11 +0000648 if (screenName != NULL)
649 Tcl_SetVar2(v->interp, "env", "DISPLAY",
650 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000651
Barry Warsawfa701a81997-01-16 00:15:11 +0000652 if (interactive)
653 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
654 else
655 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000656
Barry Warsawfa701a81997-01-16 00:15:11 +0000657 /* This is used to get the application class for Tk 4.1 and up */
658 argv0 = (char*)ckalloc(strlen(className) + 1);
659 if (!argv0) {
660 PyErr_NoMemory();
661 Py_DECREF(v);
662 return NULL;
663 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000664
Barry Warsawfa701a81997-01-16 00:15:11 +0000665 strcpy(argv0, className);
Neal Norwitz9dbc7dd2005-12-19 06:08:59 +0000666 if (isupper(Py_CHARMASK(argv0[0])))
Neal Norwitz65c05b22006-04-10 02:17:47 +0000667 argv0[0] = tolower(Py_CHARMASK(argv0[0]));
Barry Warsawfa701a81997-01-16 00:15:11 +0000668 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
669 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000670
David Aschere2b4b322004-02-18 05:59:53 +0000671 if (! wantTk) {
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000672 Tcl_SetVar(v->interp,
673 "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
David Aschere2b4b322004-02-18 05:59:53 +0000674 }
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000675#ifdef TKINTER_PROTECT_LOADTK
676 else if (tk_load_failed) {
677 Tcl_SetVar(v->interp,
678 "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY);
679 }
680#endif
David Aschere2b4b322004-02-18 05:59:53 +0000681
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000682 /* some initial arguments need to be in argv */
683 if (sync || use) {
Tim Peters51fa3b72004-08-04 02:16:48 +0000684 char *args;
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000685 int len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000686
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000687 if (sync)
688 len += sizeof "-sync";
689 if (use)
690 len += strlen(use) + sizeof "-use ";
691
Tim Peters51fa3b72004-08-04 02:16:48 +0000692 args = (char*)ckalloc(len);
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000693 if (!args) {
694 PyErr_NoMemory();
695 Py_DECREF(v);
696 return NULL;
697 }
698
699 args[0] = '\0';
700 if (sync)
701 strcat(args, "-sync");
702 if (use) {
703 if (sync)
704 strcat(args, " ");
705 strcat(args, "-use ");
706 strcat(args, use);
707 }
708
709 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
710 ckfree(args);
711 }
712
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000713 if (Tcl_AppInit(v->interp) != TCL_OK) {
714 PyObject *result = Tkinter_Error((PyObject *)v);
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000715#ifdef TKINTER_PROTECT_LOADTK
716 if (wantTk) {
717 const char *_tkinter_tk_failed;
718 _tkinter_tk_failed = Tcl_GetVar(v->interp,
719 "_tkinter_tk_failed", TCL_GLOBAL_ONLY);
720
721 if ( _tkinter_tk_failed != NULL &&
722 strcmp(_tkinter_tk_failed, "1") == 0) {
723 tk_load_failed = 1;
724 }
725 }
726#endif
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000727 Py_DECREF((PyObject *)v);
728 return (TkappObject *)result;
729 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000730
Guido van Rossum7bf15641998-05-22 18:28:17 +0000731 EnableEventHook();
732
Barry Warsawfa701a81997-01-16 00:15:11 +0000733 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000734}
735
Barry Warsawfa701a81997-01-16 00:15:11 +0000736
Guilherme Polo1972d162009-03-27 21:43:08 +0000737#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000738static void
739Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
740 Tcl_Condition *cond, Tcl_Mutex *mutex)
741{
742 Py_BEGIN_ALLOW_THREADS;
743 Tcl_MutexLock(mutex);
744 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
745 Tcl_ThreadAlert(self->thread_id);
746 Tcl_ConditionWait(cond, mutex, NULL);
747 Tcl_MutexUnlock(mutex);
748 Py_END_ALLOW_THREADS
749}
Guilherme Polo1972d162009-03-27 21:43:08 +0000750#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000751
Barry Warsawfa701a81997-01-16 00:15:11 +0000752
Guido van Rossum18468821994-06-20 07:49:28 +0000753/** Tcl Eval **/
754
Martin v. Löwisffad6332002-11-26 09:28:05 +0000755typedef struct {
756 PyObject_HEAD
757 Tcl_Obj *value;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000758 PyObject *string; /* This cannot cause cycles. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000759} PyTclObject;
760
761staticforward PyTypeObject PyTclObject_Type;
762#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
763
764static PyObject *
765newPyTclObject(Tcl_Obj *arg)
766{
767 PyTclObject *self;
768 self = PyObject_New(PyTclObject, &PyTclObject_Type);
769 if (self == NULL)
770 return NULL;
771 Tcl_IncrRefCount(arg);
772 self->value = arg;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000773 self->string = NULL;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000774 return (PyObject*)self;
775}
776
777static void
778PyTclObject_dealloc(PyTclObject *self)
779{
780 Tcl_DecrRefCount(self->value);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000781 Py_XDECREF(self->string);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000782 PyObject_Del(self);
783}
784
785static PyObject *
786PyTclObject_str(PyTclObject *self)
787{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000788 if (self->string && PyString_Check(self->string)) {
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000789 Py_INCREF(self->string);
790 return self->string;
791 }
792 /* XXX Could cache value if it is an ASCII string. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000793 return PyString_FromString(Tcl_GetString(self->value));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000794}
795
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000796static char*
797PyTclObject_TclString(PyObject *self)
798{
799 return Tcl_GetString(((PyTclObject*)self)->value);
800}
801
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000802/* Like _str, but create Unicode if necessary. */
Martin v. Löwis39195712003-01-04 00:33:13 +0000803PyDoc_STRVAR(PyTclObject_string__doc__,
804"the string representation of this object, either as string or Unicode");
805
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000806static PyObject *
807PyTclObject_string(PyTclObject *self, void *ignored)
808{
809 char *s;
810 int i, len;
811 if (!self->string) {
812 s = Tcl_GetStringFromObj(self->value, &len);
813 for (i = 0; i < len; i++)
814 if (s[i] & 0x80)
815 break;
816#ifdef Py_USING_UNICODE
817 if (i == len)
818 /* It is an ASCII string. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000819 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000820 else {
821 self->string = PyUnicode_DecodeUTF8(s, len, "strict");
822 if (!self->string) {
823 PyErr_Clear();
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000824 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000825 }
826 }
827#else
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000828 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000829#endif
830 if (!self->string)
831 return NULL;
832 }
833 Py_INCREF(self->string);
834 return self->string;
835}
836
837#ifdef Py_USING_UNICODE
Martin v. Löwis39195712003-01-04 00:33:13 +0000838PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode");
839
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000840static PyObject *
841PyTclObject_unicode(PyTclObject *self, void *ignored)
842{
843 char *s;
844 int len;
845 if (self->string && PyUnicode_Check(self->string)) {
846 Py_INCREF(self->string);
847 return self->string;
848 }
849 /* XXX Could chache result if it is non-ASCII. */
850 s = Tcl_GetStringFromObj(self->value, &len);
851 return PyUnicode_DecodeUTF8(s, len, "strict");
852}
853#endif
854
Martin v. Löwisffad6332002-11-26 09:28:05 +0000855static PyObject *
856PyTclObject_repr(PyTclObject *self)
857{
858 char buf[50];
Martin v. Löwisfba73692004-11-13 11:13:35 +0000859 PyOS_snprintf(buf, 50, "<%s object at %p>",
860 self->value->typePtr->name, self->value);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000861 return PyString_FromString(buf);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000862}
863
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000864static int
865PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
866{
867 int res;
868 res = strcmp(Tcl_GetString(self->value),
869 Tcl_GetString(other->value));
870 if (res < 0) return -1;
871 if (res > 0) return 1;
872 return 0;
873}
874
Martin v. Löwis39195712003-01-04 00:33:13 +0000875PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
876
Martin v. Löwisffad6332002-11-26 09:28:05 +0000877static PyObject*
878get_typename(PyTclObject* obj, void* ignored)
879{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000880 return PyString_FromString(obj->value->typePtr->name);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000881}
882
Martin v. Löwis39195712003-01-04 00:33:13 +0000883
Martin v. Löwisffad6332002-11-26 09:28:05 +0000884static PyGetSetDef PyTclObject_getsetlist[] = {
Martin v. Löwis39195712003-01-04 00:33:13 +0000885 {"typename", (getter)get_typename, NULL, get_typename__doc__},
886 {"string", (getter)PyTclObject_string, NULL,
887 PyTclObject_string__doc__},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000888 {0},
889};
890
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000891static PyMethodDef PyTclObject_methods[] = {
Martin v. Löwise2713be2005-03-08 15:03:08 +0000892#ifdef Py_USING_UNICODE
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000893 {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS,
Martin v. Löwis39195712003-01-04 00:33:13 +0000894 PyTclObject_unicode__doc__},
Martin v. Löwise2713be2005-03-08 15:03:08 +0000895#endif
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000896 {0}
897};
898
Martin v. Löwisffad6332002-11-26 09:28:05 +0000899statichere PyTypeObject PyTclObject_Type = {
900 PyObject_HEAD_INIT(NULL)
901 0, /*ob_size*/
902 "_tkinter.Tcl_Obj", /*tp_name*/
903 sizeof(PyTclObject), /*tp_basicsize*/
904 0, /*tp_itemsize*/
905 /* methods */
906 (destructor)PyTclObject_dealloc, /*tp_dealloc*/
907 0, /*tp_print*/
908 0, /*tp_getattr*/
909 0, /*tp_setattr*/
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000910 (cmpfunc)PyTclObject_cmp, /*tp_compare*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000911 (reprfunc)PyTclObject_repr, /*tp_repr*/
912 0, /*tp_as_number*/
913 0, /*tp_as_sequence*/
914 0, /*tp_as_mapping*/
915 0, /*tp_hash*/
916 0, /*tp_call*/
917 (reprfunc)PyTclObject_str, /*tp_str*/
Jason Tishlerfb8595d2003-01-06 12:41:26 +0000918 PyObject_GenericGetAttr,/*tp_getattro*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000919 0, /*tp_setattro*/
920 0, /*tp_as_buffer*/
921 Py_TPFLAGS_DEFAULT, /*tp_flags*/
922 0, /*tp_doc*/
923 0, /*tp_traverse*/
924 0, /*tp_clear*/
925 0, /*tp_richcompare*/
926 0, /*tp_weaklistoffset*/
927 0, /*tp_iter*/
928 0, /*tp_iternext*/
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000929 PyTclObject_methods, /*tp_methods*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000930 0, /*tp_members*/
931 PyTclObject_getsetlist, /*tp_getset*/
932 0, /*tp_base*/
933 0, /*tp_dict*/
934 0, /*tp_descr_get*/
935 0, /*tp_descr_set*/
936 0, /*tp_dictoffset*/
937 0, /*tp_init*/
938 0, /*tp_alloc*/
939 0, /*tp_new*/
940 0, /*tp_free*/
941 0, /*tp_is_gc*/
942};
943
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000944static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000945AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000946{
947 Tcl_Obj *result;
948
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000949 if (PyString_Check(value))
950 return Tcl_NewStringObj(PyString_AS_STRING(value),
951 PyString_GET_SIZE(value));
Martin v. Löwis70c3dda2003-01-22 09:17:38 +0000952 else if (PyBool_Check(value))
953 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000954 else if (PyInt_Check(value))
955 return Tcl_NewLongObj(PyInt_AS_LONG(value));
956 else if (PyFloat_Check(value))
957 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
958 else if (PyTuple_Check(value)) {
959 Tcl_Obj **argv = (Tcl_Obj**)
960 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
961 int i;
962 if(!argv)
963 return 0;
964 for(i=0;i<PyTuple_Size(value);i++)
965 argv[i] = AsObj(PyTuple_GetItem(value,i));
966 result = Tcl_NewListObj(PyTuple_Size(value), argv);
967 ckfree(FREECAST argv);
968 return result;
969 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000970#ifdef Py_USING_UNICODE
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000971 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000972 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
Neal Norwitz047f3c72006-06-12 02:06:42 +0000973 Py_ssize_t size = PyUnicode_GET_SIZE(value);
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000974 /* This #ifdef assumes that Tcl uses UCS-2.
975 See TCL_UTF_MAX test above. */
Martin v. Löwis6f29ff32003-04-16 20:34:55 +0000976#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
Guido van Rossum076d9ee2008-01-03 23:54:04 +0000977 Tcl_UniChar *outbuf = NULL;
Neal Norwitz047f3c72006-06-12 02:06:42 +0000978 Py_ssize_t i;
Guido van Rossum076d9ee2008-01-03 23:54:04 +0000979 size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
980 if (allocsize >= size)
981 outbuf = (Tcl_UniChar*)ckalloc(allocsize);
982 /* Else overflow occurred, and we take the next exit */
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000983 if (!outbuf) {
984 PyErr_NoMemory();
985 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000986 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000987 for (i = 0; i < size; i++) {
988 if (inbuf[i] >= 0x10000) {
989 /* Tcl doesn't do UTF-16, yet. */
990 PyErr_SetString(PyExc_ValueError,
991 "unsupported character");
992 ckfree(FREECAST outbuf);
993 return NULL;
994 }
995 outbuf[i] = inbuf[i];
996 }
997 result = Tcl_NewUnicodeObj(outbuf, size);
998 ckfree(FREECAST outbuf);
999 return result;
1000#else
1001 return Tcl_NewUnicodeObj(inbuf, size);
1002#endif
1003
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001004 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001005#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +00001006 else if(PyTclObject_Check(value)) {
1007 Tcl_Obj *v = ((PyTclObject*)value)->value;
1008 Tcl_IncrRefCount(v);
1009 return v;
1010 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001011 else {
1012 PyObject *v = PyObject_Str(value);
1013 if (!v)
1014 return 0;
1015 result = AsObj(v);
1016 Py_DECREF(v);
1017 return result;
1018 }
1019}
1020
Martin v. Löwisffad6332002-11-26 09:28:05 +00001021static PyObject*
1022FromObj(PyObject* tkapp, Tcl_Obj *value)
1023{
1024 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001025 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +00001026
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001027 if (value->typePtr == NULL) {
1028 /* If the result contains any bytes with the top bit set,
1029 it's UTF-8 and we should decode it to Unicode */
1030#ifdef Py_USING_UNICODE
1031 int i;
1032 char *s = value->bytes;
1033 int len = value->length;
1034 for (i = 0; i < len; i++) {
1035 if (value->bytes[i] & 0x80)
1036 break;
1037 }
1038
1039 if (i == value->length)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001040 result = PyString_FromStringAndSize(s, len);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001041 else {
1042 /* Convert UTF-8 to Unicode string */
1043 result = PyUnicode_DecodeUTF8(s, len, "strict");
1044 if (result == NULL) {
1045 PyErr_Clear();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001046 result = PyString_FromStringAndSize(s, len);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001047 }
1048 }
1049#else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001050 result = PyString_FromStringAndSize(value->bytes, value->length);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001051#endif
1052 return result;
1053 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001054
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001055 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001056 result = value->internalRep.longValue ? Py_True : Py_False;
1057 Py_INCREF(result);
1058 return result;
1059 }
1060
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001061 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001062 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +00001063 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001064 return PyString_FromStringAndSize(data, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001065 }
1066
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001067 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001068 return PyFloat_FromDouble(value->internalRep.doubleValue);
1069 }
1070
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001071 if (value->typePtr == app->IntType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001072 return PyInt_FromLong(value->internalRep.longValue);
1073 }
1074
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001075 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001076 int size;
1077 int i, status;
1078 PyObject *elem;
1079 Tcl_Obj *tcl_elem;
1080
1081 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
1082 if (status == TCL_ERROR)
1083 return Tkinter_Error(tkapp);
1084 result = PyTuple_New(size);
1085 if (!result)
1086 return NULL;
1087 for (i = 0; i < size; i++) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001088 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
Martin v. Löwisffad6332002-11-26 09:28:05 +00001089 value, i, &tcl_elem);
1090 if (status == TCL_ERROR) {
1091 Py_DECREF(result);
1092 return Tkinter_Error(tkapp);
1093 }
1094 elem = FromObj(tkapp, tcl_elem);
1095 if (!elem) {
1096 Py_DECREF(result);
1097 return NULL;
1098 }
1099 PyTuple_SetItem(result, i, elem);
1100 }
1101 return result;
1102 }
1103
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001104 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001105 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +00001106 }
1107
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001108 if (value->typePtr == app->StringType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001109#ifdef Py_USING_UNICODE
Martin v. Löwis6f29ff32003-04-16 20:34:55 +00001110#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
Martin v. Löwisffad6332002-11-26 09:28:05 +00001111 PyObject *result;
1112 int size;
1113 Tcl_UniChar *input;
1114 Py_UNICODE *output;
1115
1116 size = Tcl_GetCharLength(value);
1117 result = PyUnicode_FromUnicode(NULL, size);
1118 if (!result)
1119 return NULL;
1120 input = Tcl_GetUnicode(value);
1121 output = PyUnicode_AS_UNICODE(result);
1122 while (size--)
1123 *output++ = *input++;
1124 return result;
1125#else
1126 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1127 Tcl_GetCharLength(value));
1128#endif
1129#else
1130 int size;
1131 char *c;
1132 c = Tcl_GetStringFromObj(value, &size);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001133 return PyString_FromStringAndSize(c, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001134#endif
1135 }
1136
1137 return newPyTclObject(value);
1138}
1139
Guilherme Polo1972d162009-03-27 21:43:08 +00001140#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001141/* This mutex synchronizes inter-thread command calls. */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001142TCL_DECLARE_MUTEX(call_mutex)
1143
1144typedef struct Tkapp_CallEvent {
1145 Tcl_Event ev; /* Must be first */
1146 TkappObject *self;
1147 PyObject *args;
1148 int flags;
1149 PyObject **res;
1150 PyObject **exc_type, **exc_value, **exc_tb;
Guilherme Polo363161a2009-02-06 22:48:07 +00001151 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001152} Tkapp_CallEvent;
Guilherme Polo1972d162009-03-27 21:43:08 +00001153#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001154
1155void
1156Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001157{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001158 int i;
1159 for (i = 0; i < objc; i++)
1160 Tcl_DecrRefCount(objv[i]);
1161 if (objv != objStore)
1162 ckfree(FREECAST objv);
1163}
Guido van Rossum18468821994-06-20 07:49:28 +00001164
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001165/* Convert Python objects to Tcl objects. This must happen in the
1166 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001167
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001168static Tcl_Obj**
1169Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1170{
1171 Tcl_Obj **objv = objStore;
Martin v. Löwis7d134952002-12-12 19:05:48 +00001172 int objc = 0, i;
Guido van Rossum212643f1998-04-29 16:22:14 +00001173 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +00001174 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001175
Guido van Rossum212643f1998-04-29 16:22:14 +00001176 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +00001177 objv[0] = AsObj(args);
1178 if (objv[0] == 0)
1179 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001180 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +00001181 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001182 }
1183 else {
Guido van Rossum632de272000-03-29 00:19:50 +00001184 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001185
Guido van Rossum632de272000-03-29 00:19:50 +00001186 if (objc > ARGSZ) {
1187 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1188 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001189 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +00001190 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +00001191 goto finally;
1192 }
1193 }
1194
Guido van Rossum632de272000-03-29 00:19:50 +00001195 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001196 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +00001197 if (v == Py_None) {
1198 objc = i;
1199 break;
1200 }
Guido van Rossum632de272000-03-29 00:19:50 +00001201 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +00001202 if (!objv[i]) {
1203 /* Reset objc, so it attempts to clear
1204 objects only up to i. */
1205 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +00001206 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001207 }
Guido van Rossum632de272000-03-29 00:19:50 +00001208 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001209 }
1210 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001211 *pobjc = objc;
1212 return objv;
1213finally:
1214 Tkapp_CallDeallocArgs(objv, objStore, objc);
1215 return NULL;
1216}
Guido van Rossum212643f1998-04-29 16:22:14 +00001217
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001218/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001219
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001220static PyObject*
1221Tkapp_CallResult(TkappObject *self)
1222{
1223 PyObject *res = NULL;
1224 if(self->wantobjects) {
1225 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001226 /* Not sure whether the IncrRef is necessary, but something
1227 may overwrite the interpreter result while we are
1228 converting it. */
1229 Tcl_IncrRefCount(value);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001230 res = FromObj((PyObject*)self, value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001231 Tcl_DecrRefCount(value);
1232 } else {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001233 const char *s = Tcl_GetStringResult(self->interp);
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001234 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001235
Guido van Rossum990f5c62000-05-04 15:07:16 +00001236 /* If the result contains any bytes with the top bit set,
1237 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001238#ifdef Py_USING_UNICODE
Guido van Rossum990f5c62000-05-04 15:07:16 +00001239 while (*p != '\0') {
1240 if (*p & 0x80)
1241 break;
1242 p++;
1243 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001244
Guido van Rossum990f5c62000-05-04 15:07:16 +00001245 if (*p == '\0')
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001246 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum990f5c62000-05-04 15:07:16 +00001247 else {
1248 /* Convert UTF-8 to Unicode string */
1249 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +00001250 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
1251 if (res == NULL) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001252 PyErr_Clear();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001253 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +00001254 }
Guido van Rossum990f5c62000-05-04 15:07:16 +00001255 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001256#else
1257 p = strchr(p, '\0');
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001258 res = PyString_FromStringAndSize(s, (int)(p-s));
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001259#endif
Guido van Rossum990f5c62000-05-04 15:07:16 +00001260 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001261 return res;
1262}
Guido van Rossum632de272000-03-29 00:19:50 +00001263
Guilherme Polo1972d162009-03-27 21:43:08 +00001264#ifdef WITH_THREAD
1265
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001266/* Tkapp_CallProc is the event procedure that is executed in the context of
1267 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1268 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001269
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001270static int
1271Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1272{
1273 Tcl_Obj *objStore[ARGSZ];
1274 Tcl_Obj **objv;
1275 int objc;
1276 int i;
1277 ENTER_PYTHON
1278 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1279 if (!objv) {
1280 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1281 *(e->res) = NULL;
1282 }
1283 LEAVE_PYTHON
1284 if (!objv)
1285 goto done;
1286 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1287 ENTER_PYTHON
1288 if (i == TCL_ERROR) {
1289 *(e->res) = NULL;
1290 *(e->exc_type) = NULL;
1291 *(e->exc_tb) = NULL;
1292 *(e->exc_value) = PyObject_CallFunction(
1293 Tkinter_TclError, "s",
1294 Tcl_GetStringResult(e->self->interp));
1295 }
1296 else {
1297 *(e->res) = Tkapp_CallResult(e->self);
1298 }
1299 LEAVE_PYTHON
Guilherme Polo14ff18d2009-02-06 22:26:22 +00001300
1301 Tkapp_CallDeallocArgs(objv, objStore, objc);
1302done:
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001303 /* Wake up calling thread. */
1304 Tcl_MutexLock(&call_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00001305 Tcl_ConditionNotify(e->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001306 Tcl_MutexUnlock(&call_mutex);
1307 return 1;
1308}
1309
Guilherme Polo1972d162009-03-27 21:43:08 +00001310#endif
1311
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001312/* This is the main entry point for calling a Tcl command.
1313 It supports three cases, with regard to threading:
1314 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1315 the context of the calling thread.
1316 2. Tcl is threaded, caller of the command is in the interpreter thread:
1317 Execute the command in the calling thread. Since the Tcl lock will
1318 not be used, we can merge that with case 1.
1319 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1320 the interpreter thread. Allocation of Tcl objects needs to occur in the
1321 interpreter thread, so we ship the PyObject* args to the target thread,
1322 and perform processing there. */
1323
1324static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001325Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001326{
1327 Tcl_Obj *objStore[ARGSZ];
1328 Tcl_Obj **objv = NULL;
1329 int objc, i;
1330 PyObject *res = NULL;
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001331 TkappObject *self = (TkappObject*)selfptr;
Guilherme Polo23fe2a82009-02-02 21:08:32 +00001332 int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001333
Kurt B. Kaiserd67a3b92007-07-05 22:03:39 +00001334 /* If args is a single tuple, replace with contents of tuple */
1335 if (1 == PyTuple_Size(args)){
1336 PyObject* item = PyTuple_GetItem(args, 0);
1337 if (PyTuple_Check(item))
1338 args = item;
1339 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001340#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001341 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1342 /* We cannot call the command directly. Instead, we must
1343 marshal the parameters to the interpreter thread. */
1344 Tkapp_CallEvent *ev;
Guilherme Polo363161a2009-02-06 22:48:07 +00001345 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001346 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001347 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001348 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001349 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1350 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1351 ev->self = self;
1352 ev->args = args;
1353 ev->res = &res;
1354 ev->exc_type = &exc_type;
1355 ev->exc_value = &exc_value;
1356 ev->exc_tb = &exc_tb;
Guilherme Polo363161a2009-02-06 22:48:07 +00001357 ev->done = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001358
Guilherme Polo363161a2009-02-06 22:48:07 +00001359 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001360
1361 if (res == NULL) {
1362 if (exc_type)
1363 PyErr_Restore(exc_type, exc_value, exc_tb);
1364 else
1365 PyErr_SetObject(Tkinter_TclError, exc_value);
1366 }
Guilherme Polo363161a2009-02-06 22:48:07 +00001367 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001368 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001369 else
1370#endif
1371 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001372
1373 objv = Tkapp_CallArgs(args, objStore, &objc);
1374 if (!objv)
1375 return NULL;
1376
1377 ENTER_TCL
1378
1379 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1380
1381 ENTER_OVERLAP
1382
1383 if (i == TCL_ERROR)
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001384 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001385 else
1386 res = Tkapp_CallResult(self);
1387
1388 LEAVE_OVERLAP_TCL
1389
1390 Tkapp_CallDeallocArgs(objv, objStore, objc);
1391 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001392 return res;
1393}
1394
1395
1396static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001397Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001398{
Guido van Rossum212643f1998-04-29 16:22:14 +00001399 /* Could do the same here as for Tkapp_Call(), but this is not used
1400 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1401 way for the user to do what all its Global* variants do (save and
1402 reset the scope pointer, call the local version, restore the saved
1403 scope pointer). */
1404
Guido van Rossum62320c91998-06-15 04:36:09 +00001405 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001406 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001407
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001408 CHECK_TCL_APPARTMENT;
1409
Guido van Rossum62320c91998-06-15 04:36:09 +00001410 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001411 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001412 int err;
1413 ENTER_TCL
1414 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001415 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001416 if (err == TCL_ERROR)
1417 res = Tkinter_Error(self);
1418 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001419 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001420 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001421 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001422 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001423
1424 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001425}
1426
1427static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001428Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001429{
Barry Warsawfa701a81997-01-16 00:15:11 +00001430 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001431 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001432 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001433
Guido van Rossum43713e52000-02-29 13:59:29 +00001434 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001435 return NULL;
1436
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001437 CHECK_TCL_APPARTMENT;
1438
Guido van Rossum00d93061998-05-28 23:06:38 +00001439 ENTER_TCL
1440 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001441 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001442 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001443 res = Tkinter_Error(self);
1444 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001445 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001446 LEAVE_OVERLAP_TCL
1447 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001448}
1449
1450static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001451Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001452{
Barry Warsawfa701a81997-01-16 00:15:11 +00001453 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001454 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001455 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001456
Guido van Rossum43713e52000-02-29 13:59:29 +00001457 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001458 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001459
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001460 CHECK_TCL_APPARTMENT;
1461
Guido van Rossum00d93061998-05-28 23:06:38 +00001462 ENTER_TCL
1463 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001464 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001465 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001466 res = Tkinter_Error(self);
1467 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001468 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001469 LEAVE_OVERLAP_TCL
1470 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001471}
1472
1473static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001474Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001475{
Barry Warsawfa701a81997-01-16 00:15:11 +00001476 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001477 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001478 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001479
Guido van Rossum43713e52000-02-29 13:59:29 +00001480 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001481 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001482
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001483 CHECK_TCL_APPARTMENT;
1484
Guido van Rossum00d93061998-05-28 23:06:38 +00001485 ENTER_TCL
1486 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001487 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001488 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001489 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001490
Guido van Rossum62320c91998-06-15 04:36:09 +00001491 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001492 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001493 LEAVE_OVERLAP_TCL
1494 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001495}
1496
1497static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001498Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001499{
Barry Warsawfa701a81997-01-16 00:15:11 +00001500 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001501 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001502 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001503
Guido van Rossum35d43371997-08-02 00:09:09 +00001504 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001505 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001506
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001507 CHECK_TCL_APPARTMENT;
1508
Guido van Rossum00d93061998-05-28 23:06:38 +00001509 ENTER_TCL
1510 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001511 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001512 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001513 res = Tkinter_Error(self);
1514 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001515 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001516 LEAVE_OVERLAP_TCL
1517 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001518}
1519
1520static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001521Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001522{
Barry Warsawfa701a81997-01-16 00:15:11 +00001523 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001524
Guido van Rossum43713e52000-02-29 13:59:29 +00001525 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001526 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001527 CHECK_TCL_APPARTMENT;
1528
Guido van Rossum00d93061998-05-28 23:06:38 +00001529 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001530 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001531 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001532
Barry Warsawfa701a81997-01-16 00:15:11 +00001533 Py_INCREF(Py_None);
1534 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001535}
1536
Barry Warsawfa701a81997-01-16 00:15:11 +00001537
1538
Guido van Rossum18468821994-06-20 07:49:28 +00001539/** Tcl Variable **/
1540
Guilherme Polo1972d162009-03-27 21:43:08 +00001541typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
1542
1543#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001544TCL_DECLARE_MUTEX(var_mutex)
1545
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001546typedef struct VarEvent {
1547 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001548 PyObject *self;
1549 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001550 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001551 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001552 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001553 PyObject **exc_type;
1554 PyObject **exc_val;
Guilherme Polo363161a2009-02-06 22:48:07 +00001555 Tcl_Condition *cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001556} VarEvent;
Guilherme Polo1972d162009-03-27 21:43:08 +00001557#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001558
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001559static int
1560varname_converter(PyObject *in, void *_out)
1561{
1562 char **out = (char**)_out;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001563 if (PyString_Check(in)) {
1564 *out = PyString_AsString(in);
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001565 return 1;
1566 }
1567 if (PyTclObject_Check(in)) {
1568 *out = PyTclObject_TclString(in);
1569 return 1;
1570 }
1571 /* XXX: Should give diagnostics. */
1572 return 0;
1573}
1574
Guilherme Polo1972d162009-03-27 21:43:08 +00001575#ifdef WITH_THREAD
1576
Martin v. Löwis111c1802008-06-13 07:47:47 +00001577static void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001578var_perform(VarEvent *ev)
1579{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001580 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1581 if (!*(ev->res)) {
1582 PyObject *exc, *val, *tb;
1583 PyErr_Fetch(&exc, &val, &tb);
1584 PyErr_NormalizeException(&exc, &val, &tb);
1585 *(ev->exc_type) = exc;
1586 *(ev->exc_val) = val;
1587 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001588 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001589
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001590}
1591
1592static int
1593var_proc(VarEvent* ev, int flags)
1594{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001595 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001596 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001597 Tcl_MutexLock(&var_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00001598 Tcl_ConditionNotify(ev->cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001599 Tcl_MutexUnlock(&var_mutex);
1600 LEAVE_PYTHON
1601 return 1;
1602}
1603
Guilherme Polo1972d162009-03-27 21:43:08 +00001604#endif
1605
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001606static PyObject*
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001607var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001608{
Martin v. Löwisa9656492003-03-30 08:44:58 +00001609#ifdef WITH_THREAD
Guilherme Polo1972d162009-03-27 21:43:08 +00001610 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001611 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001612 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001613 VarEvent *ev;
1614 PyObject *res, *exc_type, *exc_val;
Guilherme Polo363161a2009-02-06 22:48:07 +00001615 Tcl_Condition cond = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001616
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001617 /* The current thread is not the interpreter thread. Marshal
1618 the call to the interpreter thread, then wait for
1619 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001620 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001621 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001622
1623 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1624
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001625 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001626 ev->args = args;
1627 ev->flags = flags;
1628 ev->func = func;
1629 ev->res = &res;
1630 ev->exc_type = &exc_type;
1631 ev->exc_val = &exc_val;
Guilherme Polo363161a2009-02-06 22:48:07 +00001632 ev->cond = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001633 ev->ev.proc = (Tcl_EventProc*)var_proc;
Guilherme Polo363161a2009-02-06 22:48:07 +00001634 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
1635 Tcl_ConditionFinalize(&cond);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001636 if (!res) {
1637 PyErr_SetObject(exc_type, exc_val);
1638 Py_DECREF(exc_type);
1639 Py_DECREF(exc_val);
1640 return NULL;
1641 }
1642 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001643 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001644#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001645 /* Tcl is not threaded, or this is the interpreter thread. */
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001646 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001647}
1648
Guido van Rossum18468821994-06-20 07:49:28 +00001649static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001650SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001651{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001652 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001653 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001654 PyObject *res = NULL;
1655 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001656
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001657 if (PyArg_ParseTuple(args, "O&O:setvar",
1658 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001659 /* XXX Acquire tcl lock??? */
1660 newval = AsObj(newValue);
1661 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001662 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001663 ENTER_TCL
1664 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1665 newval, flags);
1666 ENTER_OVERLAP
1667 if (!ok)
1668 Tkinter_Error(self);
1669 else {
1670 res = Py_None;
1671 Py_INCREF(res);
1672 }
1673 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001674 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001675 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001676 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001677 if (PyArg_ParseTuple(args, "ssO:setvar",
1678 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001679 /* XXX must hold tcl lock already??? */
1680 newval = AsObj(newValue);
1681 ENTER_TCL
1682 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1683 ENTER_OVERLAP
1684 if (!ok)
1685 Tkinter_Error(self);
1686 else {
1687 res = Py_None;
1688 Py_INCREF(res);
1689 }
1690 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001691 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001692 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001693 return NULL;
1694 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001695 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001696 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001697}
1698
1699static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001700Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001701{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001702 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001703}
1704
1705static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001706Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001707{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001708 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001709}
1710
Barry Warsawfa701a81997-01-16 00:15:11 +00001711
1712
Guido van Rossum18468821994-06-20 07:49:28 +00001713static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001714GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001715{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001716 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001717 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001718 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001719
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001720 if (!PyArg_ParseTuple(args, "O&|s:getvar",
1721 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001722 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001723
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001724 ENTER_TCL
1725 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1726 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001727 if (tres == NULL) {
1728 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1729 } else {
1730 if (((TkappObject*)self)->wantobjects) {
1731 res = FromObj(self, tres);
1732 }
1733 else {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001734 res = PyString_FromString(Tcl_GetString(tres));
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001735 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001736 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001737 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001738 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001739}
1740
1741static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001742Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001743{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001744 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001745}
1746
1747static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001748Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001749{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001750 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001751}
1752
Barry Warsawfa701a81997-01-16 00:15:11 +00001753
1754
Guido van Rossum18468821994-06-20 07:49:28 +00001755static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001756UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001757{
Guido van Rossum35d43371997-08-02 00:09:09 +00001758 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001759 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001760 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001761
Guido van Rossum43713e52000-02-29 13:59:29 +00001762 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001763 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001764
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001765 ENTER_TCL
1766 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1767 ENTER_OVERLAP
1768 if (code == TCL_ERROR)
1769 res = Tkinter_Error(self);
1770 else {
1771 Py_INCREF(Py_None);
1772 res = Py_None;
1773 }
1774 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001775 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001776}
1777
1778static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001779Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001780{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001781 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001782}
1783
1784static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001785Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001786{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001787 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001788}
1789
Barry Warsawfa701a81997-01-16 00:15:11 +00001790
1791
Guido van Rossum18468821994-06-20 07:49:28 +00001792/** Tcl to Python **/
1793
1794static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001795Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001796{
Barry Warsawfa701a81997-01-16 00:15:11 +00001797 char *s;
1798 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001799
Martin v. Löwisffad6332002-11-26 09:28:05 +00001800 if (PyTuple_Size(args) == 1) {
1801 PyObject* o = PyTuple_GetItem(args, 0);
1802 if (PyInt_Check(o)) {
1803 Py_INCREF(o);
1804 return o;
1805 }
1806 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001807 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001808 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001809 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001810 return Tkinter_Error(self);
1811 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001812}
1813
1814static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001815Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001816{
Barry Warsawfa701a81997-01-16 00:15:11 +00001817 char *s;
1818 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001819
Martin v. Löwisffad6332002-11-26 09:28:05 +00001820 if (PyTuple_Size(args) == 1) {
1821 PyObject *o = PyTuple_GetItem(args, 0);
1822 if (PyFloat_Check(o)) {
1823 Py_INCREF(o);
1824 return o;
1825 }
1826 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001827 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001828 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001829 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001830 return Tkinter_Error(self);
1831 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001832}
1833
1834static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001835Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001836{
Barry Warsawfa701a81997-01-16 00:15:11 +00001837 char *s;
1838 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001839
Martin v. Löwisffad6332002-11-26 09:28:05 +00001840 if (PyTuple_Size(args) == 1) {
1841 PyObject *o = PyTuple_GetItem(args, 0);
1842 if (PyInt_Check(o)) {
1843 Py_INCREF(o);
1844 return o;
1845 }
1846 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001847 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001848 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001849 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1850 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001851 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001852}
1853
1854static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001855Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001856{
Barry Warsawfa701a81997-01-16 00:15:11 +00001857 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001858 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001859 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001860
Guido van Rossum43713e52000-02-29 13:59:29 +00001861 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001862 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001863
1864 CHECK_TCL_APPARTMENT;
1865
Guido van Rossum00d93061998-05-28 23:06:38 +00001866 ENTER_TCL
1867 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001868 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001869 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001870 res = Tkinter_Error(self);
1871 else
1872 res = Py_BuildValue("s", Tkapp_Result(self));
1873 LEAVE_OVERLAP_TCL
1874 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001875}
1876
1877static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001878Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001879{
Barry Warsawfa701a81997-01-16 00:15:11 +00001880 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001881 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001882 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001883 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001884
Guido van Rossum43713e52000-02-29 13:59:29 +00001885 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001886 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001887
1888 CHECK_TCL_APPARTMENT;
1889
Guido van Rossum00d93061998-05-28 23:06:38 +00001890 ENTER_TCL
1891 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001892 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001893 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001894 res = Tkinter_Error(self);
1895 else
1896 res = Py_BuildValue("l", v);
1897 LEAVE_OVERLAP_TCL
1898 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001899}
1900
1901static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001902Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001903{
Barry Warsawfa701a81997-01-16 00:15:11 +00001904 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001905 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001906 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001907 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001908
Guido van Rossum43713e52000-02-29 13:59:29 +00001909 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001910 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001911 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001912 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001913 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001914 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001915 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001916 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001917 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001918 res = Tkinter_Error(self);
1919 else
1920 res = Py_BuildValue("d", v);
1921 LEAVE_OVERLAP_TCL
1922 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001923}
1924
1925static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001926Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001927{
Barry Warsawfa701a81997-01-16 00:15:11 +00001928 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001929 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001930 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001931 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001932
Guido van Rossum43713e52000-02-29 13:59:29 +00001933 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001934 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001935 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001936 ENTER_TCL
1937 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001938 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001939 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001940 res = Tkinter_Error(self);
1941 else
1942 res = Py_BuildValue("i", v);
1943 LEAVE_OVERLAP_TCL
1944 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001945}
1946
Barry Warsawfa701a81997-01-16 00:15:11 +00001947
1948
Guido van Rossum18468821994-06-20 07:49:28 +00001949static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001950Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001951{
Barry Warsawfa701a81997-01-16 00:15:11 +00001952 char *list;
1953 int argc;
1954 char **argv;
1955 PyObject *v;
1956 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001957
Martin v. Löwisffad6332002-11-26 09:28:05 +00001958 if (PyTuple_Size(args) == 1) {
1959 v = PyTuple_GetItem(args, 0);
1960 if (PyTuple_Check(v)) {
1961 Py_INCREF(v);
1962 return v;
1963 }
1964 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001965 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001966 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001967
Neal Norwitzd1c55102003-05-29 00:17:03 +00001968 if (Tcl_SplitList(Tkapp_Interp(self), list,
1969 &argc, &argv) == TCL_ERROR) {
1970 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001971 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001972 }
Guido van Rossum18468821994-06-20 07:49:28 +00001973
Barry Warsawfa701a81997-01-16 00:15:11 +00001974 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001975 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001976
Barry Warsawfa701a81997-01-16 00:15:11 +00001977 for (i = 0; i < argc; i++) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001978 PyObject *s = PyString_FromString(argv[i]);
Barry Warsawfa701a81997-01-16 00:15:11 +00001979 if (!s || PyTuple_SetItem(v, i, s)) {
1980 Py_DECREF(v);
1981 v = NULL;
1982 goto finally;
1983 }
1984 }
Guido van Rossum18468821994-06-20 07:49:28 +00001985
Barry Warsawfa701a81997-01-16 00:15:11 +00001986 finally:
1987 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001988 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001989 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001990}
1991
1992static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001993Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001994{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001995 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001996 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001997
Martin v. Löwisffad6332002-11-26 09:28:05 +00001998 if (PyTuple_Size(args) == 1) {
1999 PyObject* o = PyTuple_GetItem(args, 0);
2000 if (PyTuple_Check(o)) {
2001 o = SplitObj(o);
2002 return o;
2003 }
2004 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00002005 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00002006 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00002007 v = Split(list);
2008 PyMem_Free(list);
2009 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00002010}
2011
2012static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002013Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002014{
Barry Warsawfa701a81997-01-16 00:15:11 +00002015 char *s = Merge(args);
2016 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002017
Barry Warsawfa701a81997-01-16 00:15:11 +00002018 if (s) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002019 res = PyString_FromString(s);
Barry Warsawfa701a81997-01-16 00:15:11 +00002020 ckfree(s);
2021 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002022
2023 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00002024}
2025
Barry Warsawfa701a81997-01-16 00:15:11 +00002026
2027
Guido van Rossum18468821994-06-20 07:49:28 +00002028/** Tcl Command **/
2029
Guido van Rossum00d93061998-05-28 23:06:38 +00002030/* Client data struct */
2031typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00002032 PyObject *self;
2033 PyObject *func;
2034} PythonCmd_ClientData;
2035
2036static int
Fred Drake509d79a2000-07-08 04:04:38 +00002037PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00002038{
2039 errorInCmd = 1;
2040 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2041 LEAVE_PYTHON
2042 return TCL_ERROR;
2043}
2044
Guido van Rossum18468821994-06-20 07:49:28 +00002045/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00002046 * function or method.
2047 */
Guido van Rossum18468821994-06-20 07:49:28 +00002048static int
Fred Drake509d79a2000-07-08 04:04:38 +00002049PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00002050{
Guido van Rossum00d93061998-05-28 23:06:38 +00002051 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002052 PyObject *self, *func, *arg, *res;
Guido van Rossum2834b972000-10-06 16:58:26 +00002053 int i, rv;
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002054 Tcl_Obj *obj_res;
Guido van Rossum18468821994-06-20 07:49:28 +00002055
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002056 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002057
Barry Warsawfa701a81997-01-16 00:15:11 +00002058 /* TBD: no error checking here since we know, via the
2059 * Tkapp_CreateCommand() that the client data is a two-tuple
2060 */
Guido van Rossum00d93061998-05-28 23:06:38 +00002061 self = data->self;
2062 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00002063
Barry Warsawfa701a81997-01-16 00:15:11 +00002064 /* Create argument list (argv1, ..., argvN) */
2065 if (!(arg = PyTuple_New(argc - 1)))
2066 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00002067
Barry Warsawfa701a81997-01-16 00:15:11 +00002068 for (i = 0; i < (argc - 1); i++) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002069 PyObject *s = PyString_FromString(argv[i + 1]);
Barry Warsawfa701a81997-01-16 00:15:11 +00002070 if (!s || PyTuple_SetItem(arg, i, s)) {
2071 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00002072 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00002073 }
2074 }
2075 res = PyEval_CallObject(func, arg);
2076 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00002077
Barry Warsawfa701a81997-01-16 00:15:11 +00002078 if (res == NULL)
2079 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00002080
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002081 obj_res = AsObj(res);
2082 if (obj_res == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002083 Py_DECREF(res);
2084 return PythonCmd_Error(interp);
2085 }
Guido van Rossum2834b972000-10-06 16:58:26 +00002086 else {
Guilherme Polo3768b2f2009-03-07 01:47:49 +00002087 Tcl_SetObjResult(interp, obj_res);
Guido van Rossum2834b972000-10-06 16:58:26 +00002088 rv = TCL_OK;
2089 }
2090
Barry Warsawfa701a81997-01-16 00:15:11 +00002091 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00002092
Guido van Rossum00d93061998-05-28 23:06:38 +00002093 LEAVE_PYTHON
2094
Guido van Rossum2834b972000-10-06 16:58:26 +00002095 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002096}
2097
2098static void
Fred Drake509d79a2000-07-08 04:04:38 +00002099PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002100{
Guido van Rossum00d93061998-05-28 23:06:38 +00002101 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2102
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002103 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002104 Py_XDECREF(data->self);
2105 Py_XDECREF(data->func);
2106 PyMem_DEL(data);
2107 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002108}
2109
Barry Warsawfa701a81997-01-16 00:15:11 +00002110
2111
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002112
Guilherme Polo1972d162009-03-27 21:43:08 +00002113#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002114TCL_DECLARE_MUTEX(command_mutex)
2115
2116typedef struct CommandEvent{
2117 Tcl_Event ev;
2118 Tcl_Interp* interp;
2119 char *name;
2120 int create;
2121 int *status;
2122 ClientData *data;
Guilherme Polo363161a2009-02-06 22:48:07 +00002123 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002124} CommandEvent;
2125
2126static int
2127Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002128{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002129 if (ev->create)
2130 *ev->status = Tcl_CreateCommand(
2131 ev->interp, ev->name, PythonCmd,
2132 ev->data, PythonCmdDelete) == NULL;
2133 else
2134 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2135 Tcl_MutexLock(&command_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00002136 Tcl_ConditionNotify(ev->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002137 Tcl_MutexUnlock(&command_mutex);
2138 return 1;
2139}
Guilherme Polo1972d162009-03-27 21:43:08 +00002140#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002141
2142static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002143Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002144{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002145 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002146 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002147 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002148 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002149 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002150
Guido van Rossum43713e52000-02-29 13:59:29 +00002151 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002152 return NULL;
2153 if (!PyCallable_Check(func)) {
2154 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002155 return NULL;
2156 }
Guido van Rossum18468821994-06-20 07:49:28 +00002157
Martin v. Löwisa9656492003-03-30 08:44:58 +00002158#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002159 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002160 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002161 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002162#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002163
Guido van Rossum00d93061998-05-28 23:06:38 +00002164 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002165 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002166 return PyErr_NoMemory();
Neal Norwitzce5b3c32006-07-16 02:02:57 +00002167 Py_INCREF(self);
2168 Py_INCREF(func);
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002169 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002170 data->func = func;
Guilherme Polo1972d162009-03-27 21:43:08 +00002171
2172#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002173 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo363161a2009-02-06 22:48:07 +00002174 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002175 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2176 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2177 ev->interp = self->interp;
2178 ev->create = 1;
2179 ev->name = cmdName;
2180 ev->data = (ClientData)data;
2181 ev->status = &err;
Guilherme Polo363161a2009-02-06 22:48:07 +00002182 ev->done = &cond;
2183 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
2184 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002185 }
Guilherme Polo1972d162009-03-27 21:43:08 +00002186 else
2187#endif
2188 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002189 ENTER_TCL
2190 err = Tcl_CreateCommand(
2191 Tkapp_Interp(self), cmdName, PythonCmd,
2192 (ClientData)data, PythonCmdDelete) == NULL;
2193 LEAVE_TCL
2194 }
2195 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002196 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002197 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002198 return NULL;
2199 }
Guido van Rossum18468821994-06-20 07:49:28 +00002200
Barry Warsawfa701a81997-01-16 00:15:11 +00002201 Py_INCREF(Py_None);
2202 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002203}
2204
Barry Warsawfa701a81997-01-16 00:15:11 +00002205
2206
Guido van Rossum18468821994-06-20 07:49:28 +00002207static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002208Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002209{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002210 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002211 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002212 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002213
Guido van Rossum43713e52000-02-29 13:59:29 +00002214 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002215 return NULL;
Guilherme Polo1972d162009-03-27 21:43:08 +00002216
2217#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002218 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo363161a2009-02-06 22:48:07 +00002219 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002220 CommandEvent *ev;
2221 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2222 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2223 ev->interp = self->interp;
2224 ev->create = 0;
2225 ev->name = cmdName;
2226 ev->status = &err;
Guilherme Polo363161a2009-02-06 22:48:07 +00002227 ev->done = &cond;
2228 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002229 &command_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00002230 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002231 }
Guilherme Polo1972d162009-03-27 21:43:08 +00002232 else
2233#endif
2234 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002235 ENTER_TCL
2236 err = Tcl_DeleteCommand(self->interp, cmdName);
2237 LEAVE_TCL
2238 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002239 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002240 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2241 return NULL;
2242 }
2243 Py_INCREF(Py_None);
2244 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002245}
2246
Barry Warsawfa701a81997-01-16 00:15:11 +00002247
2248
Guido van Rossum00d93061998-05-28 23:06:38 +00002249#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002250/** File Handler **/
2251
Guido van Rossum00d93061998-05-28 23:06:38 +00002252typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002253 PyObject *func;
2254 PyObject *file;
2255 int id;
2256 struct _fhcdata *next;
2257} FileHandler_ClientData;
2258
2259static FileHandler_ClientData *HeadFHCD;
2260
2261static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002262NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002263{
2264 FileHandler_ClientData *p;
2265 p = PyMem_NEW(FileHandler_ClientData, 1);
2266 if (p != NULL) {
2267 Py_XINCREF(func);
2268 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002269 p->func = func;
2270 p->file = file;
2271 p->id = id;
2272 p->next = HeadFHCD;
2273 HeadFHCD = p;
2274 }
2275 return p;
2276}
2277
2278static void
Fred Drake509d79a2000-07-08 04:04:38 +00002279DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002280{
2281 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002282
2283 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002284 while ((p = *pp) != NULL) {
2285 if (p->id == id) {
2286 *pp = p->next;
2287 Py_XDECREF(p->func);
2288 Py_XDECREF(p->file);
2289 PyMem_DEL(p);
2290 }
2291 else
2292 pp = &p->next;
2293 }
2294}
2295
Guido van Rossuma597dde1995-01-10 20:56:29 +00002296static void
Fred Drake509d79a2000-07-08 04:04:38 +00002297FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002298{
Guido van Rossum00d93061998-05-28 23:06:38 +00002299 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002300 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002301
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002302 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002303 func = data->func;
2304 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002305
Barry Warsawfa701a81997-01-16 00:15:11 +00002306 arg = Py_BuildValue("(Oi)", file, (long) mask);
2307 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002308 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002309
2310 if (res == NULL) {
2311 errorInCmd = 1;
2312 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2313 }
2314 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002315 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002316}
2317
Guido van Rossum18468821994-06-20 07:49:28 +00002318static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002319Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2320 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002321{
Guido van Rossum00d93061998-05-28 23:06:38 +00002322 FileHandler_ClientData *data;
2323 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002324 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002325
Guilherme Poloe7f14032009-01-03 21:51:09 +00002326 if (!self && Py_Py3kWarningFlag) {
2327 if (PyErr_Warn(PyExc_DeprecationWarning,
2328 "_tkinter.createfilehandler is gone in 3.x") < 0)
2329 return NULL;
2330 }
2331
Guido van Rossum2834b972000-10-06 16:58:26 +00002332 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2333 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002334 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002335
Martin v. Löwisa9656492003-03-30 08:44:58 +00002336#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002337 if (!self && !tcl_lock) {
2338 /* We don't have the Tcl lock since Tcl is threaded. */
2339 PyErr_SetString(PyExc_RuntimeError,
2340 "_tkinter.createfilehandler not supported "
2341 "for threaded Tcl");
2342 return NULL;
2343 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002344#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002345
2346 if (self) {
2347 CHECK_TCL_APPARTMENT;
2348 }
2349
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002350 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002351 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002352 return NULL;
2353 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002354 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002355 return NULL;
2356 }
2357
Guido van Rossuma80649b2000-03-28 20:07:05 +00002358 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002359 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002360 return NULL;
2361
Barry Warsawfa701a81997-01-16 00:15:11 +00002362 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002363 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002364 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002365 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002366 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002367 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002368}
2369
2370static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002371Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002372{
Barry Warsawfa701a81997-01-16 00:15:11 +00002373 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002374 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002375
Guilherme Poloe7f14032009-01-03 21:51:09 +00002376 if (!self && Py_Py3kWarningFlag) {
2377 if (PyErr_Warn(PyExc_DeprecationWarning,
2378 "_tkinter.deletefilehandler is gone in 3.x") < 0)
2379 return NULL;
2380 }
2381
Guido van Rossum43713e52000-02-29 13:59:29 +00002382 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002383 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002384
Martin v. Löwisa9656492003-03-30 08:44:58 +00002385#ifdef WITH_THREAD
Neal Norwitz12e22172003-03-03 21:16:39 +00002386 if (!self && !tcl_lock) {
2387 /* We don't have the Tcl lock since Tcl is threaded. */
2388 PyErr_SetString(PyExc_RuntimeError,
2389 "_tkinter.deletefilehandler not supported "
2390 "for threaded Tcl");
2391 return NULL;
2392 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002393#endif
Neal Norwitz12e22172003-03-03 21:16:39 +00002394
2395 if (self) {
2396 CHECK_TCL_APPARTMENT;
2397 }
2398
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002399 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002400 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002401 return NULL;
2402
Guido van Rossuma80649b2000-03-28 20:07:05 +00002403 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002404
Barry Warsawfa701a81997-01-16 00:15:11 +00002405 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002406 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002407 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002408 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002409 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002410 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002411}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002412#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002413
Barry Warsawfa701a81997-01-16 00:15:11 +00002414
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002415/**** Tktt Object (timer token) ****/
2416
Jeremy Hylton938ace62002-07-17 16:30:39 +00002417static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002418
Guido van Rossum00d93061998-05-28 23:06:38 +00002419typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002420 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002421 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002422 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002423} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002424
2425static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002426Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002427{
Barry Warsawfa701a81997-01-16 00:15:11 +00002428 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002429 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002430
Guido van Rossum43713e52000-02-29 13:59:29 +00002431 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002432 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002433 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002434 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002435 v->token = NULL;
2436 }
2437 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002438 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002439 Py_DECREF(func);
2440 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002441 }
2442 Py_INCREF(Py_None);
2443 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002444}
2445
2446static PyMethodDef Tktt_methods[] =
2447{
Neal Norwitzb0493252002-03-31 14:44:22 +00002448 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002449 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002450};
2451
2452static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002453Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002454{
Barry Warsawfa701a81997-01-16 00:15:11 +00002455 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002456
Guido van Rossumb18618d2000-05-03 23:44:39 +00002457 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002458 if (v == NULL)
2459 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002460
Guido van Rossum00d93061998-05-28 23:06:38 +00002461 Py_INCREF(func);
2462 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002463 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002464
2465 /* Extra reference, deleted when called or when handler is deleted */
2466 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002467 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002468}
2469
2470static void
Fred Drake509d79a2000-07-08 04:04:38 +00002471Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002472{
Guido van Rossum00d93061998-05-28 23:06:38 +00002473 TkttObject *v = (TkttObject *)self;
2474 PyObject *func = v->func;
2475
2476 Py_XDECREF(func);
2477
Guido van Rossumb18618d2000-05-03 23:44:39 +00002478 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002479}
2480
Guido van Rossum597ac201998-05-12 14:36:19 +00002481static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002482Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002483{
Barry Warsawfa701a81997-01-16 00:15:11 +00002484 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002485 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002486
Tim Peters885d4572001-11-28 20:27:42 +00002487 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002488 v->func == NULL ? ", handler deleted" : "");
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002489 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002490}
2491
2492static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002493Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002494{
Barry Warsawfa701a81997-01-16 00:15:11 +00002495 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002496}
2497
2498static PyTypeObject Tktt_Type =
2499{
Martin v. Löwis68192102007-07-21 06:55:02 +00002500 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002501 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002502 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002503 0, /*tp_itemsize */
2504 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002505 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00002506 Tktt_GetAttr, /*tp_getattr */
2507 0, /*tp_setattr */
2508 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00002509 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002510 0, /*tp_as_number */
2511 0, /*tp_as_sequence */
2512 0, /*tp_as_mapping */
2513 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002514};
2515
Barry Warsawfa701a81997-01-16 00:15:11 +00002516
2517
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002518/** Timer Handler **/
2519
2520static void
Fred Drake509d79a2000-07-08 04:04:38 +00002521TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002522{
Guido van Rossum00d93061998-05-28 23:06:38 +00002523 TkttObject *v = (TkttObject *)clientData;
2524 PyObject *func = v->func;
2525 PyObject *res;
2526
2527 if (func == NULL)
2528 return;
2529
2530 v->func = NULL;
2531
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002532 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002533
2534 res = PyEval_CallObject(func, NULL);
2535 Py_DECREF(func);
2536 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002537
Barry Warsawfa701a81997-01-16 00:15:11 +00002538 if (res == NULL) {
2539 errorInCmd = 1;
2540 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2541 }
2542 else
2543 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002544
2545 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002546}
2547
2548static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002549Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002550{
Barry Warsawfa701a81997-01-16 00:15:11 +00002551 int milliseconds;
2552 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002553 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002554
Guilherme Poloe7f14032009-01-03 21:51:09 +00002555 if (!self && Py_Py3kWarningFlag) {
2556 if (PyErr_Warn(PyExc_DeprecationWarning,
2557 "_tkinter.createtimerhandler is gone in 3.x") < 0)
2558 return NULL;
2559 }
2560
Guido van Rossum2834b972000-10-06 16:58:26 +00002561 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2562 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002563 return NULL;
2564 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002565 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002566 return NULL;
2567 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002568
Martin v. Löwisa9656492003-03-30 08:44:58 +00002569#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002570 if (!self && !tcl_lock) {
2571 /* We don't have the Tcl lock since Tcl is threaded. */
2572 PyErr_SetString(PyExc_RuntimeError,
2573 "_tkinter.createtimerhandler not supported "
2574 "for threaded Tcl");
2575 return NULL;
2576 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002577#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002578
2579 if (self) {
2580 CHECK_TCL_APPARTMENT;
2581 }
2582
Guido van Rossum00d93061998-05-28 23:06:38 +00002583 v = Tktt_New(func);
Neal Norwitz5f17d9a2006-08-12 02:33:36 +00002584 if (v) {
2585 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2586 (ClientData)v);
2587 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002588
Guido van Rossum00d93061998-05-28 23:06:38 +00002589 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002590}
2591
Barry Warsawfa701a81997-01-16 00:15:11 +00002592
Guido van Rossum18468821994-06-20 07:49:28 +00002593/** Event Loop **/
2594
Guido van Rossum18468821994-06-20 07:49:28 +00002595static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002596Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002597{
Barry Warsawfa701a81997-01-16 00:15:11 +00002598 int threshold = 0;
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002599 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002600#ifdef WITH_THREAD
2601 PyThreadState *tstate = PyThreadState_Get();
2602#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002603
Guilherme Poloe7f14032009-01-03 21:51:09 +00002604 if (!self && Py_Py3kWarningFlag) {
2605 if (PyErr_Warn(PyExc_DeprecationWarning,
2606 "_tkinter.mainloop is gone in 3.x") < 0)
2607 return NULL;
2608 }
2609
Guido van Rossum43713e52000-02-29 13:59:29 +00002610 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002611 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002612
Martin v. Löwisa9656492003-03-30 08:44:58 +00002613#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002614 if (!self && !tcl_lock) {
2615 /* We don't have the Tcl lock since Tcl is threaded. */
2616 PyErr_SetString(PyExc_RuntimeError,
2617 "_tkinter.mainloop not supported "
2618 "for threaded Tcl");
2619 return NULL;
2620 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002621#endif
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002622
2623 if (self) {
2624 CHECK_TCL_APPARTMENT;
2625 self->dispatching = 1;
2626 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002627
Barry Warsawfa701a81997-01-16 00:15:11 +00002628 quitMainLoop = 0;
2629 while (Tk_GetNumMainWindows() > threshold &&
2630 !quitMainLoop &&
2631 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002632 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002633 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002634
2635#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002636 if (self && self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002637 /* Allow other Python threads to run. */
2638 ENTER_TCL
2639 result = Tcl_DoOneEvent(0);
2640 LEAVE_TCL
2641 }
2642 else {
2643 Py_BEGIN_ALLOW_THREADS
2644 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2645 tcl_tstate = tstate;
2646 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2647 tcl_tstate = NULL;
2648 if(tcl_lock)PyThread_release_lock(tcl_lock);
2649 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002650 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002651 Py_END_ALLOW_THREADS
2652 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002653#else
2654 result = Tcl_DoOneEvent(0);
2655#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002656
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002657 if (PyErr_CheckSignals() != 0) {
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002658 if (self)
2659 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002660 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002661 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002662 if (result < 0)
2663 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002664 }
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002665 if (self)
2666 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002667 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002668
Barry Warsawfa701a81997-01-16 00:15:11 +00002669 if (errorInCmd) {
2670 errorInCmd = 0;
2671 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2672 excInCmd = valInCmd = trbInCmd = NULL;
2673 return NULL;
2674 }
2675 Py_INCREF(Py_None);
2676 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002677}
2678
2679static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002680Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002681{
Guido van Rossum35d43371997-08-02 00:09:09 +00002682 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002683 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002684
Guilherme Poloe7f14032009-01-03 21:51:09 +00002685 if (!self && Py_Py3kWarningFlag) {
2686 if (PyErr_Warn(PyExc_DeprecationWarning,
2687 "_tkinter.dooneevent is gone in 3.x") < 0)
2688 return NULL;
2689 }
2690
Guido van Rossum43713e52000-02-29 13:59:29 +00002691 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002692 return NULL;
2693
Guido van Rossum00d93061998-05-28 23:06:38 +00002694 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002695 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002696 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002697 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002698}
2699
2700static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002701Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002702{
2703
Guilherme Poloe7f14032009-01-03 21:51:09 +00002704 if (!self && Py_Py3kWarningFlag) {
2705 if (PyErr_Warn(PyExc_DeprecationWarning,
Guilherme Polo41eb0862009-03-28 19:17:16 +00002706 "_tkinter.quit is gone in 3.x") < 0)
Guilherme Poloe7f14032009-01-03 21:51:09 +00002707 return NULL;
2708 }
2709
Guido van Rossum43713e52000-02-29 13:59:29 +00002710 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002711 return NULL;
2712
2713 quitMainLoop = 1;
2714 Py_INCREF(Py_None);
2715 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002716}
2717
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002718static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002719Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002720{
2721
Guido van Rossum43713e52000-02-29 13:59:29 +00002722 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002723 return NULL;
2724
2725 return PyInt_FromLong((long)Tkapp_Interp(self));
2726}
2727
David Aschere2b4b322004-02-18 05:59:53 +00002728static PyObject *
2729Tkapp_TkInit(PyObject *self, PyObject *args)
2730{
2731 Tcl_Interp *interp = Tkapp_Interp(self);
David Aschere2b4b322004-02-18 05:59:53 +00002732 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002733 int err;
David Aschere2b4b322004-02-18 05:59:53 +00002734
Guilherme Poloa66cf5b2009-02-09 20:50:27 +00002735#ifdef TKINTER_PROTECT_LOADTK
2736 /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the
2737 * first call failed.
2738 * To avoid the deadlock, we just refuse the second call through
2739 * a static variable.
2740 */
2741 if (tk_load_failed) {
2742 PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG);
Martin v. Löwis86725192006-05-01 06:28:01 +00002743 return NULL;
2744 }
Guilherme Poloa66cf5b2009-02-09 20:50:27 +00002745#endif
2746
David Aschere2b4b322004-02-18 05:59:53 +00002747 /* We want to guard against calling Tk_Init() multiple times */
2748 CHECK_TCL_APPARTMENT;
2749 ENTER_TCL
2750 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2751 ENTER_OVERLAP
2752 if (err == TCL_ERROR) {
Martin v. Löwis86725192006-05-01 06:28:01 +00002753 /* This sets an exception, but we cannot return right
2754 away because we need to exit the overlap first. */
2755 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002756 } else {
2757 _tk_exists = Tkapp_Result(self);
2758 }
2759 LEAVE_OVERLAP_TCL
2760 if (err == TCL_ERROR) {
2761 return NULL;
2762 }
2763 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2764 if (Tk_Init(interp) == TCL_ERROR) {
Guilherme Poloa66cf5b2009-02-09 20:50:27 +00002765 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
2766#ifdef TKINTER_PROTECT_LOADTK
2767 tk_load_failed = 1;
2768#endif
David Aschere2b4b322004-02-18 05:59:53 +00002769 return NULL;
2770 }
2771 }
2772 Py_INCREF(Py_None);
2773 return Py_None;
2774}
Barry Warsawfa701a81997-01-16 00:15:11 +00002775
Martin v. Löwisffad6332002-11-26 09:28:05 +00002776static PyObject *
2777Tkapp_WantObjects(PyObject *self, PyObject *args)
2778{
2779
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002780 int wantobjects = -1;
2781 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002782 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002783 if (wantobjects == -1)
2784 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002785 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002786
2787 Py_INCREF(Py_None);
2788 return Py_None;
2789}
2790
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002791static PyObject *
2792Tkapp_WillDispatch(PyObject *self, PyObject *args)
2793{
2794
2795 ((TkappObject*)self)->dispatching = 1;
2796
2797 Py_INCREF(Py_None);
2798 return Py_None;
2799}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002800
Barry Warsawfa701a81997-01-16 00:15:11 +00002801
Guido van Rossum18468821994-06-20 07:49:28 +00002802/**** Tkapp Method List ****/
2803
2804static PyMethodDef Tkapp_methods[] =
2805{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002806 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002807 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Neal Norwitze2e447b2007-05-22 07:16:10 +00002808 {"call", Tkapp_Call, METH_VARARGS},
2809 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002810 {"eval", Tkapp_Eval, METH_VARARGS},
2811 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2812 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2813 {"record", Tkapp_Record, METH_VARARGS},
2814 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2815 {"setvar", Tkapp_SetVar, METH_VARARGS},
2816 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2817 {"getvar", Tkapp_GetVar, METH_VARARGS},
2818 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2819 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2820 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2821 {"getint", Tkapp_GetInt, METH_VARARGS},
2822 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2823 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2824 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2825 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2826 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2827 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2828 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2829 {"split", Tkapp_Split, METH_VARARGS},
Neal Norwitze2e447b2007-05-22 07:16:10 +00002830 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002831 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2832 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002833#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002834 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2835 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002836#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002837 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2838 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2839 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2840 {"quit", Tkapp_Quit, METH_VARARGS},
2841 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002842 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002843 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002844};
2845
Barry Warsawfa701a81997-01-16 00:15:11 +00002846
2847
Guido van Rossum18468821994-06-20 07:49:28 +00002848/**** Tkapp Type Methods ****/
2849
2850static void
Fred Drake509d79a2000-07-08 04:04:38 +00002851Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002852{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002853 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002854 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002855 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002856 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002857 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002858 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002859}
2860
2861static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002862Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002863{
Guido van Rossum35d43371997-08-02 00:09:09 +00002864 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002865}
2866
2867static PyTypeObject Tkapp_Type =
2868{
Martin v. Löwis68192102007-07-21 06:55:02 +00002869 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002870 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002871 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002872 0, /*tp_itemsize */
2873 Tkapp_Dealloc, /*tp_dealloc */
2874 0, /*tp_print */
2875 Tkapp_GetAttr, /*tp_getattr */
2876 0, /*tp_setattr */
2877 0, /*tp_compare */
2878 0, /*tp_repr */
2879 0, /*tp_as_number */
2880 0, /*tp_as_sequence */
2881 0, /*tp_as_mapping */
2882 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002883};
2884
Barry Warsawfa701a81997-01-16 00:15:11 +00002885
2886
Guido van Rossum18468821994-06-20 07:49:28 +00002887/**** Tkinter Module ****/
2888
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002889typedef struct {
2890 PyObject* tuple;
2891 int size; /* current size */
2892 int maxsize; /* allocated size */
2893} FlattenContext;
2894
2895static int
2896_bump(FlattenContext* context, int size)
2897{
Guido van Rossum2834b972000-10-06 16:58:26 +00002898 /* expand tuple to hold (at least) size new items.
2899 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002900
2901 int maxsize = context->maxsize * 2;
2902
2903 if (maxsize < context->size + size)
2904 maxsize = context->size + size;
2905
2906 context->maxsize = maxsize;
2907
Tim Peters4324aa32001-05-28 22:30:08 +00002908 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002909}
2910
2911static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002912_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002913{
2914 /* add tuple or list to argument tuple (recursively) */
2915
2916 int i, size;
2917
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002918 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002919 PyErr_SetString(PyExc_ValueError,
2920 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002921 return 0;
2922 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002923 size = PyList_GET_SIZE(item);
2924 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002925 if (context->size + size > context->maxsize &&
2926 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002927 return 0;
2928 /* copy items to output tuple */
2929 for (i = 0; i < size; i++) {
2930 PyObject *o = PyList_GET_ITEM(item, i);
2931 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002932 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002933 return 0;
2934 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002935 if (context->size + 1 > context->maxsize &&
2936 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002937 return 0;
2938 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002939 PyTuple_SET_ITEM(context->tuple,
2940 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002941 }
2942 }
2943 } else if (PyTuple_Check(item)) {
2944 /* same, for tuples */
2945 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002946 if (context->size + size > context->maxsize &&
2947 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002948 return 0;
2949 for (i = 0; i < size; i++) {
2950 PyObject *o = PyTuple_GET_ITEM(item, i);
2951 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002952 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002953 return 0;
2954 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002955 if (context->size + 1 > context->maxsize &&
2956 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002957 return 0;
2958 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002959 PyTuple_SET_ITEM(context->tuple,
2960 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002961 }
2962 }
2963 } else {
2964 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2965 return 0;
2966 }
2967 return 1;
2968}
2969
2970static PyObject *
2971Tkinter_Flatten(PyObject* self, PyObject* args)
2972{
2973 FlattenContext context;
2974 PyObject* item;
2975
2976 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2977 return NULL;
2978
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002979 context.maxsize = PySequence_Size(item);
Benjamin Petersonb3619be2009-01-30 02:24:39 +00002980 if (context.maxsize < 0)
2981 return NULL;
2982 if (context.maxsize == 0)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002983 return PyTuple_New(0);
2984
2985 context.tuple = PyTuple_New(context.maxsize);
2986 if (!context.tuple)
2987 return NULL;
2988
2989 context.size = 0;
2990
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002991 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002992 return NULL;
2993
Tim Peters4324aa32001-05-28 22:30:08 +00002994 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002995 return NULL;
2996
2997 return context.tuple;
2998}
2999
Guido van Rossum18468821994-06-20 07:49:28 +00003000static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003001Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00003002{
Barry Warsawfa701a81997-01-16 00:15:11 +00003003 char *screenName = NULL;
3004 char *baseName = NULL;
3005 char *className = NULL;
3006 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00003007 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00003008 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00003009 int sync = 0; /* pass -sync to wish */
3010 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00003011
Guido van Rossum35d43371997-08-02 00:09:09 +00003012 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00003013 if (baseName != NULL)
3014 baseName++;
3015 else
3016 baseName = Py_GetProgramName();
3017 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00003018
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00003019 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00003020 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00003021 &interactive, &wantobjects, &wantTk,
3022 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00003023 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00003024
Barry Warsawfa701a81997-01-16 00:15:11 +00003025 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00003026 interactive, wantobjects, wantTk,
3027 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00003028}
3029
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003030static PyObject *
3031Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
3032{
3033 int new_val;
3034 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
3035 return NULL;
3036 if (new_val < 0) {
3037 PyErr_SetString(PyExc_ValueError,
3038 "busywaitinterval must be >= 0");
3039 return NULL;
3040 }
3041 Tkinter_busywaitinterval = new_val;
3042 Py_INCREF(Py_None);
3043 return Py_None;
3044}
3045
3046static char setbusywaitinterval_doc[] =
3047"setbusywaitinterval(n) -> None\n\
3048\n\
3049Set the busy-wait interval in milliseconds between successive\n\
3050calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
3051It should be set to a divisor of the maximum time between\n\
3052frames in an animation.";
3053
3054static PyObject *
3055Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
3056{
3057 return PyInt_FromLong(Tkinter_busywaitinterval);
3058}
3059
3060static char getbusywaitinterval_doc[] =
3061"getbusywaitinterval() -> int\n\
3062\n\
3063Return the current busy-wait interval between successive\n\
3064calls to Tcl_DoOneEvent in a threaded Python interpreter.";
3065
Guido van Rossum18468821994-06-20 07:49:28 +00003066static PyMethodDef moduleMethods[] =
3067{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003068 {"_flatten", Tkinter_Flatten, METH_VARARGS},
3069 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00003070#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003071 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
3072 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00003073#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003074 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
3075 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
3076 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
3077 {"quit", Tkapp_Quit, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003078 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
3079 setbusywaitinterval_doc},
3080 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
3081 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00003082 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00003083};
3084
Guido van Rossum7bf15641998-05-22 18:28:17 +00003085#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003086
3087static int stdin_ready = 0;
3088
Guido van Rossumad4db171998-06-13 13:56:28 +00003089#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00003090static void
Fred Drake509d79a2000-07-08 04:04:38 +00003091MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003092{
3093 stdin_ready = 1;
3094}
Guido van Rossumad4db171998-06-13 13:56:28 +00003095#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003096
Martin v. Löwisa9656492003-03-30 08:44:58 +00003097#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003098static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00003099#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00003100
Guido van Rossum18468821994-06-20 07:49:28 +00003101static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003102EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003103{
Guido van Rossumad4db171998-06-13 13:56:28 +00003104#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00003105 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00003106#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003107#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003108 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003109#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003110 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00003111 errorInCmd = 0;
3112#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00003113 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003114 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00003115#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003116 while (!errorInCmd && !stdin_ready) {
3117 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00003118#ifdef MS_WINDOWS
3119 if (_kbhit()) {
3120 stdin_ready = 1;
3121 break;
3122 }
3123#endif
3124#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00003125 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003126 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00003127 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003128
Guido van Rossum00d93061998-05-28 23:06:38 +00003129 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003130
3131 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003132 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00003133 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003134 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00003135 Py_END_ALLOW_THREADS
3136#else
3137 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003138#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003139
3140 if (result < 0)
3141 break;
3142 }
Guido van Rossumad4db171998-06-13 13:56:28 +00003143#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00003144 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00003145#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003146 if (errorInCmd) {
3147 errorInCmd = 0;
3148 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3149 excInCmd = valInCmd = trbInCmd = NULL;
3150 PyErr_Print();
3151 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003152#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003153 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003154#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003155 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00003156}
Guido van Rossum18468821994-06-20 07:49:28 +00003157
Guido van Rossum00d93061998-05-28 23:06:38 +00003158#endif
3159
Guido van Rossum7bf15641998-05-22 18:28:17 +00003160static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003161EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003162{
Guido van Rossum00d93061998-05-28 23:06:38 +00003163#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003164 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003165#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003166 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003167#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003168 PyOS_InputHook = EventHook;
3169 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003170#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003171}
3172
3173static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003174DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003175{
Guido van Rossum00d93061998-05-28 23:06:38 +00003176#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003177 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3178 PyOS_InputHook = NULL;
3179 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003180#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003181}
3182
Barry Warsawfa701a81997-01-16 00:15:11 +00003183
3184/* all errors will be checked in one fell swoop in init_tkinter() */
3185static void
Fred Drake509d79a2000-07-08 04:04:38 +00003186ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003187{
3188 PyObject *v = PyInt_FromLong(val);
3189 if (v) {
3190 PyDict_SetItemString(d, name, v);
3191 Py_DECREF(v);
3192 }
3193}
3194static void
Fred Drake509d79a2000-07-08 04:04:38 +00003195ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003196{
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003197 PyObject *v = PyString_FromString(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003198 if (v) {
3199 PyDict_SetItemString(d, name, v);
3200 Py_DECREF(v);
3201 }
3202}
3203
3204
Mark Hammond62b1ab12002-07-23 06:31:15 +00003205PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003206init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003207{
Barry Warsawfa701a81997-01-16 00:15:11 +00003208 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00003209
Christian Heimese93237d2007-12-19 02:37:44 +00003210 Py_TYPE(&Tkapp_Type) = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00003211
3212#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003213 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003214#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003215
Barry Warsawfa701a81997-01-16 00:15:11 +00003216 m = Py_InitModule("_tkinter", moduleMethods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003217 if (m == NULL)
3218 return;
Guido van Rossum18468821994-06-20 07:49:28 +00003219
Barry Warsawfa701a81997-01-16 00:15:11 +00003220 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003221 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003222 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003223
Guido van Rossum35d43371997-08-02 00:09:09 +00003224 ins_long(d, "READABLE", TCL_READABLE);
3225 ins_long(d, "WRITABLE", TCL_WRITABLE);
3226 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3227 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3228 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3229 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3230 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3231 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3232 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003233 ins_string(d, "TK_VERSION", TK_VERSION);
3234 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003235
Guido van Rossum83551bf1997-09-13 00:44:23 +00003236 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003237
Christian Heimese93237d2007-12-19 02:37:44 +00003238 Py_TYPE(&Tktt_Type) = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003239 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3240
Christian Heimese93237d2007-12-19 02:37:44 +00003241 Py_TYPE(&PyTclObject_Type) = &PyType_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003242 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003243
3244#ifdef TK_AQUA
3245 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3246 * start waking up. Note that Tcl_FindExecutable will do this, this
3247 * code must be above it! The original warning from
3248 * tkMacOSXAppInit.c is copied below.
3249 *
3250 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3251 * Tcl interpreter for now. It probably should work to do this
3252 * in the other order, but for now it doesn't seem to.
3253 *
3254 */
3255 Tk_MacOSXSetupTkNotifier();
3256#endif
3257
3258
Guido van Rossume187b0e2000-03-27 21:46:29 +00003259 /* This helps the dynamic loader; in Unicode aware Tcl versions
3260 it also helps Tcl find its encodings. */
3261 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00003262
Barry Warsawfa701a81997-01-16 00:15:11 +00003263 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003264 return;
3265
Guido van Rossum43ff8681998-07-14 18:02:13 +00003266#if 0
3267 /* This was not a good idea; through <Destroy> bindings,
3268 Tcl_Finalize() may invoke Python code but at that point the
3269 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003270 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003271#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003272
Guido van Rossum18468821994-06-20 07:49:28 +00003273}