blob: db25f864e60bf1e627b68e3e4484be650a5c2c09 [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;
Brett Cannon99ac9142010-05-03 23:41:51 +00002052 PyObject *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 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00002062
Barry Warsawfa701a81997-01-16 00:15:11 +00002063 /* Create argument list (argv1, ..., argvN) */
2064 if (!(arg = PyTuple_New(argc - 1)))
2065 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00002066
Barry Warsawfa701a81997-01-16 00:15:11 +00002067 for (i = 0; i < (argc - 1); i++) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002068 PyObject *s = PyString_FromString(argv[i + 1]);
Barry Warsawfa701a81997-01-16 00:15:11 +00002069 if (!s || PyTuple_SetItem(arg, i, s)) {
2070 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00002071 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00002072 }
2073 }
2074 res = PyEval_CallObject(func, arg);
2075 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00002076
Barry Warsawfa701a81997-01-16 00:15:11 +00002077 if (res == NULL)
2078 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00002079
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002080 obj_res = AsObj(res);
2081 if (obj_res == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002082 Py_DECREF(res);
2083 return PythonCmd_Error(interp);
2084 }
Guido van Rossum2834b972000-10-06 16:58:26 +00002085 else {
Guilherme Polo3768b2f2009-03-07 01:47:49 +00002086 Tcl_SetObjResult(interp, obj_res);
Guido van Rossum2834b972000-10-06 16:58:26 +00002087 rv = TCL_OK;
2088 }
2089
Barry Warsawfa701a81997-01-16 00:15:11 +00002090 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00002091
Guido van Rossum00d93061998-05-28 23:06:38 +00002092 LEAVE_PYTHON
2093
Guido van Rossum2834b972000-10-06 16:58:26 +00002094 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002095}
2096
2097static void
Fred Drake509d79a2000-07-08 04:04:38 +00002098PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002099{
Guido van Rossum00d93061998-05-28 23:06:38 +00002100 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2101
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002102 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002103 Py_XDECREF(data->self);
2104 Py_XDECREF(data->func);
2105 PyMem_DEL(data);
2106 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002107}
2108
Barry Warsawfa701a81997-01-16 00:15:11 +00002109
2110
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002111
Guilherme Polo1972d162009-03-27 21:43:08 +00002112#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002113TCL_DECLARE_MUTEX(command_mutex)
2114
2115typedef struct CommandEvent{
2116 Tcl_Event ev;
2117 Tcl_Interp* interp;
2118 char *name;
2119 int create;
2120 int *status;
2121 ClientData *data;
Guilherme Polo363161a2009-02-06 22:48:07 +00002122 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002123} CommandEvent;
2124
2125static int
2126Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002127{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002128 if (ev->create)
2129 *ev->status = Tcl_CreateCommand(
2130 ev->interp, ev->name, PythonCmd,
2131 ev->data, PythonCmdDelete) == NULL;
2132 else
2133 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2134 Tcl_MutexLock(&command_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00002135 Tcl_ConditionNotify(ev->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002136 Tcl_MutexUnlock(&command_mutex);
2137 return 1;
2138}
Guilherme Polo1972d162009-03-27 21:43:08 +00002139#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002140
2141static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002142Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002143{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002144 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002145 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002146 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002147 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002148 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002149
Guido van Rossum43713e52000-02-29 13:59:29 +00002150 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002151 return NULL;
2152 if (!PyCallable_Check(func)) {
2153 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002154 return NULL;
2155 }
Guido van Rossum18468821994-06-20 07:49:28 +00002156
Martin v. Löwisa9656492003-03-30 08:44:58 +00002157#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002158 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002159 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002160 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002161#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002162
Guido van Rossum00d93061998-05-28 23:06:38 +00002163 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002164 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002165 return PyErr_NoMemory();
Neal Norwitzce5b3c32006-07-16 02:02:57 +00002166 Py_INCREF(self);
2167 Py_INCREF(func);
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002168 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002169 data->func = func;
Guilherme Polo1972d162009-03-27 21:43:08 +00002170
2171#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002172 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo363161a2009-02-06 22:48:07 +00002173 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002174 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2175 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2176 ev->interp = self->interp;
2177 ev->create = 1;
2178 ev->name = cmdName;
2179 ev->data = (ClientData)data;
2180 ev->status = &err;
Guilherme Polo363161a2009-02-06 22:48:07 +00002181 ev->done = &cond;
2182 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
2183 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002184 }
Guilherme Polo1972d162009-03-27 21:43:08 +00002185 else
2186#endif
2187 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002188 ENTER_TCL
2189 err = Tcl_CreateCommand(
2190 Tkapp_Interp(self), cmdName, PythonCmd,
2191 (ClientData)data, PythonCmdDelete) == NULL;
2192 LEAVE_TCL
2193 }
2194 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002195 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002196 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002197 return NULL;
2198 }
Guido van Rossum18468821994-06-20 07:49:28 +00002199
Barry Warsawfa701a81997-01-16 00:15:11 +00002200 Py_INCREF(Py_None);
2201 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002202}
2203
Barry Warsawfa701a81997-01-16 00:15:11 +00002204
2205
Guido van Rossum18468821994-06-20 07:49:28 +00002206static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002207Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002208{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002209 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002210 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002211 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002212
Guido van Rossum43713e52000-02-29 13:59:29 +00002213 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002214 return NULL;
Guilherme Polo1972d162009-03-27 21:43:08 +00002215
2216#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002217 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo363161a2009-02-06 22:48:07 +00002218 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002219 CommandEvent *ev;
2220 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2221 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2222 ev->interp = self->interp;
2223 ev->create = 0;
2224 ev->name = cmdName;
2225 ev->status = &err;
Guilherme Polo363161a2009-02-06 22:48:07 +00002226 ev->done = &cond;
2227 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002228 &command_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00002229 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002230 }
Guilherme Polo1972d162009-03-27 21:43:08 +00002231 else
2232#endif
2233 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002234 ENTER_TCL
2235 err = Tcl_DeleteCommand(self->interp, cmdName);
2236 LEAVE_TCL
2237 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002238 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002239 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2240 return NULL;
2241 }
2242 Py_INCREF(Py_None);
2243 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002244}
2245
Barry Warsawfa701a81997-01-16 00:15:11 +00002246
2247
Guido van Rossum00d93061998-05-28 23:06:38 +00002248#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002249/** File Handler **/
2250
Guido van Rossum00d93061998-05-28 23:06:38 +00002251typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002252 PyObject *func;
2253 PyObject *file;
2254 int id;
2255 struct _fhcdata *next;
2256} FileHandler_ClientData;
2257
2258static FileHandler_ClientData *HeadFHCD;
2259
2260static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002261NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002262{
2263 FileHandler_ClientData *p;
2264 p = PyMem_NEW(FileHandler_ClientData, 1);
2265 if (p != NULL) {
2266 Py_XINCREF(func);
2267 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002268 p->func = func;
2269 p->file = file;
2270 p->id = id;
2271 p->next = HeadFHCD;
2272 HeadFHCD = p;
2273 }
2274 return p;
2275}
2276
2277static void
Fred Drake509d79a2000-07-08 04:04:38 +00002278DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002279{
2280 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002281
2282 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002283 while ((p = *pp) != NULL) {
2284 if (p->id == id) {
2285 *pp = p->next;
2286 Py_XDECREF(p->func);
2287 Py_XDECREF(p->file);
2288 PyMem_DEL(p);
2289 }
2290 else
2291 pp = &p->next;
2292 }
2293}
2294
Guido van Rossuma597dde1995-01-10 20:56:29 +00002295static void
Fred Drake509d79a2000-07-08 04:04:38 +00002296FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002297{
Guido van Rossum00d93061998-05-28 23:06:38 +00002298 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002299 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002300
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002301 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002302 func = data->func;
2303 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002304
Barry Warsawfa701a81997-01-16 00:15:11 +00002305 arg = Py_BuildValue("(Oi)", file, (long) mask);
2306 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002307 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002308
2309 if (res == NULL) {
2310 errorInCmd = 1;
2311 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2312 }
2313 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002314 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002315}
2316
Guido van Rossum18468821994-06-20 07:49:28 +00002317static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002318Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2319 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002320{
Guido van Rossum00d93061998-05-28 23:06:38 +00002321 FileHandler_ClientData *data;
2322 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002323 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002324
Guilherme Poloe7f14032009-01-03 21:51:09 +00002325 if (!self && Py_Py3kWarningFlag) {
2326 if (PyErr_Warn(PyExc_DeprecationWarning,
2327 "_tkinter.createfilehandler is gone in 3.x") < 0)
2328 return NULL;
2329 }
2330
Guido van Rossum2834b972000-10-06 16:58:26 +00002331 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2332 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002333 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002334
Martin v. Löwisa9656492003-03-30 08:44:58 +00002335#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002336 if (!self && !tcl_lock) {
2337 /* We don't have the Tcl lock since Tcl is threaded. */
2338 PyErr_SetString(PyExc_RuntimeError,
2339 "_tkinter.createfilehandler not supported "
2340 "for threaded Tcl");
2341 return NULL;
2342 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002343#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002344
2345 if (self) {
2346 CHECK_TCL_APPARTMENT;
2347 }
2348
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002349 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002350 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002351 return NULL;
2352 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002353 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002354 return NULL;
2355 }
2356
Guido van Rossuma80649b2000-03-28 20:07:05 +00002357 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002358 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002359 return NULL;
2360
Barry Warsawfa701a81997-01-16 00:15:11 +00002361 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002362 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002363 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002364 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002365 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002366 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002367}
2368
2369static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002370Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002371{
Barry Warsawfa701a81997-01-16 00:15:11 +00002372 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002373 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002374
Guilherme Poloe7f14032009-01-03 21:51:09 +00002375 if (!self && Py_Py3kWarningFlag) {
2376 if (PyErr_Warn(PyExc_DeprecationWarning,
2377 "_tkinter.deletefilehandler is gone in 3.x") < 0)
2378 return NULL;
2379 }
2380
Guido van Rossum43713e52000-02-29 13:59:29 +00002381 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002382 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002383
Martin v. Löwisa9656492003-03-30 08:44:58 +00002384#ifdef WITH_THREAD
Neal Norwitz12e22172003-03-03 21:16:39 +00002385 if (!self && !tcl_lock) {
2386 /* We don't have the Tcl lock since Tcl is threaded. */
2387 PyErr_SetString(PyExc_RuntimeError,
2388 "_tkinter.deletefilehandler not supported "
2389 "for threaded Tcl");
2390 return NULL;
2391 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002392#endif
Neal Norwitz12e22172003-03-03 21:16:39 +00002393
2394 if (self) {
2395 CHECK_TCL_APPARTMENT;
2396 }
2397
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002398 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002399 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002400 return NULL;
2401
Guido van Rossuma80649b2000-03-28 20:07:05 +00002402 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002403
Barry Warsawfa701a81997-01-16 00:15:11 +00002404 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002405 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002406 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002407 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002408 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002409 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002410}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002411#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002412
Barry Warsawfa701a81997-01-16 00:15:11 +00002413
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002414/**** Tktt Object (timer token) ****/
2415
Jeremy Hylton938ace62002-07-17 16:30:39 +00002416static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002417
Guido van Rossum00d93061998-05-28 23:06:38 +00002418typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002419 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002420 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002421 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002422} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002423
2424static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002425Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002426{
Barry Warsawfa701a81997-01-16 00:15:11 +00002427 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002428 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002429
Guido van Rossum43713e52000-02-29 13:59:29 +00002430 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002431 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002432 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002433 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002434 v->token = NULL;
2435 }
2436 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002437 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002438 Py_DECREF(func);
2439 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002440 }
2441 Py_INCREF(Py_None);
2442 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002443}
2444
2445static PyMethodDef Tktt_methods[] =
2446{
Neal Norwitzb0493252002-03-31 14:44:22 +00002447 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002448 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002449};
2450
2451static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002452Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002453{
Barry Warsawfa701a81997-01-16 00:15:11 +00002454 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002455
Guido van Rossumb18618d2000-05-03 23:44:39 +00002456 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002457 if (v == NULL)
2458 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002459
Guido van Rossum00d93061998-05-28 23:06:38 +00002460 Py_INCREF(func);
2461 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002462 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002463
2464 /* Extra reference, deleted when called or when handler is deleted */
2465 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002466 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002467}
2468
2469static void
Fred Drake509d79a2000-07-08 04:04:38 +00002470Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002471{
Guido van Rossum00d93061998-05-28 23:06:38 +00002472 TkttObject *v = (TkttObject *)self;
2473 PyObject *func = v->func;
2474
2475 Py_XDECREF(func);
2476
Guido van Rossumb18618d2000-05-03 23:44:39 +00002477 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002478}
2479
Guido van Rossum597ac201998-05-12 14:36:19 +00002480static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002481Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002482{
Barry Warsawfa701a81997-01-16 00:15:11 +00002483 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002484 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002485
Tim Peters885d4572001-11-28 20:27:42 +00002486 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002487 v->func == NULL ? ", handler deleted" : "");
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002488 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002489}
2490
2491static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002492Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002493{
Barry Warsawfa701a81997-01-16 00:15:11 +00002494 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002495}
2496
2497static PyTypeObject Tktt_Type =
2498{
Martin v. Löwis68192102007-07-21 06:55:02 +00002499 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002500 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002501 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002502 0, /*tp_itemsize */
2503 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002504 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00002505 Tktt_GetAttr, /*tp_getattr */
2506 0, /*tp_setattr */
2507 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00002508 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002509 0, /*tp_as_number */
2510 0, /*tp_as_sequence */
2511 0, /*tp_as_mapping */
2512 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002513};
2514
Barry Warsawfa701a81997-01-16 00:15:11 +00002515
2516
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002517/** Timer Handler **/
2518
2519static void
Fred Drake509d79a2000-07-08 04:04:38 +00002520TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002521{
Guido van Rossum00d93061998-05-28 23:06:38 +00002522 TkttObject *v = (TkttObject *)clientData;
2523 PyObject *func = v->func;
2524 PyObject *res;
2525
2526 if (func == NULL)
2527 return;
2528
2529 v->func = NULL;
2530
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002531 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002532
2533 res = PyEval_CallObject(func, NULL);
2534 Py_DECREF(func);
2535 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002536
Barry Warsawfa701a81997-01-16 00:15:11 +00002537 if (res == NULL) {
2538 errorInCmd = 1;
2539 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2540 }
2541 else
2542 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002543
2544 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002545}
2546
2547static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002548Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002549{
Barry Warsawfa701a81997-01-16 00:15:11 +00002550 int milliseconds;
2551 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002552 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002553
Guilherme Poloe7f14032009-01-03 21:51:09 +00002554 if (!self && Py_Py3kWarningFlag) {
2555 if (PyErr_Warn(PyExc_DeprecationWarning,
2556 "_tkinter.createtimerhandler is gone in 3.x") < 0)
2557 return NULL;
2558 }
2559
Guido van Rossum2834b972000-10-06 16:58:26 +00002560 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2561 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002562 return NULL;
2563 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002564 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002565 return NULL;
2566 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002567
Martin v. Löwisa9656492003-03-30 08:44:58 +00002568#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002569 if (!self && !tcl_lock) {
2570 /* We don't have the Tcl lock since Tcl is threaded. */
2571 PyErr_SetString(PyExc_RuntimeError,
2572 "_tkinter.createtimerhandler not supported "
2573 "for threaded Tcl");
2574 return NULL;
2575 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002576#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002577
2578 if (self) {
2579 CHECK_TCL_APPARTMENT;
2580 }
2581
Guido van Rossum00d93061998-05-28 23:06:38 +00002582 v = Tktt_New(func);
Neal Norwitz5f17d9a2006-08-12 02:33:36 +00002583 if (v) {
2584 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2585 (ClientData)v);
2586 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002587
Guido van Rossum00d93061998-05-28 23:06:38 +00002588 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002589}
2590
Barry Warsawfa701a81997-01-16 00:15:11 +00002591
Guido van Rossum18468821994-06-20 07:49:28 +00002592/** Event Loop **/
2593
Guido van Rossum18468821994-06-20 07:49:28 +00002594static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002595Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002596{
Barry Warsawfa701a81997-01-16 00:15:11 +00002597 int threshold = 0;
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002598 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002599#ifdef WITH_THREAD
2600 PyThreadState *tstate = PyThreadState_Get();
2601#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002602
Guilherme Poloe7f14032009-01-03 21:51:09 +00002603 if (!self && Py_Py3kWarningFlag) {
2604 if (PyErr_Warn(PyExc_DeprecationWarning,
2605 "_tkinter.mainloop is gone in 3.x") < 0)
2606 return NULL;
2607 }
2608
Guido van Rossum43713e52000-02-29 13:59:29 +00002609 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002610 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002611
Martin v. Löwisa9656492003-03-30 08:44:58 +00002612#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002613 if (!self && !tcl_lock) {
2614 /* We don't have the Tcl lock since Tcl is threaded. */
2615 PyErr_SetString(PyExc_RuntimeError,
2616 "_tkinter.mainloop not supported "
2617 "for threaded Tcl");
2618 return NULL;
2619 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002620#endif
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002621
2622 if (self) {
2623 CHECK_TCL_APPARTMENT;
2624 self->dispatching = 1;
2625 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002626
Barry Warsawfa701a81997-01-16 00:15:11 +00002627 quitMainLoop = 0;
2628 while (Tk_GetNumMainWindows() > threshold &&
2629 !quitMainLoop &&
2630 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002631 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002632 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002633
2634#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002635 if (self && self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002636 /* Allow other Python threads to run. */
2637 ENTER_TCL
2638 result = Tcl_DoOneEvent(0);
2639 LEAVE_TCL
2640 }
2641 else {
2642 Py_BEGIN_ALLOW_THREADS
2643 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2644 tcl_tstate = tstate;
2645 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2646 tcl_tstate = NULL;
2647 if(tcl_lock)PyThread_release_lock(tcl_lock);
2648 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002649 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002650 Py_END_ALLOW_THREADS
2651 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002652#else
2653 result = Tcl_DoOneEvent(0);
2654#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002655
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002656 if (PyErr_CheckSignals() != 0) {
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002657 if (self)
2658 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002659 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002660 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002661 if (result < 0)
2662 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002663 }
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002664 if (self)
2665 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002666 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002667
Barry Warsawfa701a81997-01-16 00:15:11 +00002668 if (errorInCmd) {
2669 errorInCmd = 0;
2670 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2671 excInCmd = valInCmd = trbInCmd = NULL;
2672 return NULL;
2673 }
2674 Py_INCREF(Py_None);
2675 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002676}
2677
2678static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002679Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002680{
Guido van Rossum35d43371997-08-02 00:09:09 +00002681 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002682 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002683
Guilherme Poloe7f14032009-01-03 21:51:09 +00002684 if (!self && Py_Py3kWarningFlag) {
2685 if (PyErr_Warn(PyExc_DeprecationWarning,
2686 "_tkinter.dooneevent is gone in 3.x") < 0)
2687 return NULL;
2688 }
2689
Guido van Rossum43713e52000-02-29 13:59:29 +00002690 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002691 return NULL;
2692
Guido van Rossum00d93061998-05-28 23:06:38 +00002693 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002694 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002695 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002696 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002697}
2698
2699static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002700Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002701{
2702
Guilherme Poloe7f14032009-01-03 21:51:09 +00002703 if (!self && Py_Py3kWarningFlag) {
2704 if (PyErr_Warn(PyExc_DeprecationWarning,
Guilherme Polo41eb0862009-03-28 19:17:16 +00002705 "_tkinter.quit is gone in 3.x") < 0)
Guilherme Poloe7f14032009-01-03 21:51:09 +00002706 return NULL;
2707 }
2708
Guido van Rossum43713e52000-02-29 13:59:29 +00002709 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002710 return NULL;
2711
2712 quitMainLoop = 1;
2713 Py_INCREF(Py_None);
2714 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002715}
2716
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002717static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002718Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002719{
2720
Guido van Rossum43713e52000-02-29 13:59:29 +00002721 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002722 return NULL;
2723
2724 return PyInt_FromLong((long)Tkapp_Interp(self));
2725}
2726
David Aschere2b4b322004-02-18 05:59:53 +00002727static PyObject *
2728Tkapp_TkInit(PyObject *self, PyObject *args)
2729{
2730 Tcl_Interp *interp = Tkapp_Interp(self);
David Aschere2b4b322004-02-18 05:59:53 +00002731 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002732 int err;
David Aschere2b4b322004-02-18 05:59:53 +00002733
Guilherme Poloa66cf5b2009-02-09 20:50:27 +00002734#ifdef TKINTER_PROTECT_LOADTK
2735 /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the
2736 * first call failed.
2737 * To avoid the deadlock, we just refuse the second call through
2738 * a static variable.
2739 */
2740 if (tk_load_failed) {
2741 PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG);
Martin v. Löwis86725192006-05-01 06:28:01 +00002742 return NULL;
2743 }
Guilherme Poloa66cf5b2009-02-09 20:50:27 +00002744#endif
2745
David Aschere2b4b322004-02-18 05:59:53 +00002746 /* We want to guard against calling Tk_Init() multiple times */
2747 CHECK_TCL_APPARTMENT;
2748 ENTER_TCL
2749 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2750 ENTER_OVERLAP
2751 if (err == TCL_ERROR) {
Martin v. Löwis86725192006-05-01 06:28:01 +00002752 /* This sets an exception, but we cannot return right
2753 away because we need to exit the overlap first. */
2754 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002755 } else {
2756 _tk_exists = Tkapp_Result(self);
2757 }
2758 LEAVE_OVERLAP_TCL
2759 if (err == TCL_ERROR) {
2760 return NULL;
2761 }
2762 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2763 if (Tk_Init(interp) == TCL_ERROR) {
Guilherme Poloa66cf5b2009-02-09 20:50:27 +00002764 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
2765#ifdef TKINTER_PROTECT_LOADTK
2766 tk_load_failed = 1;
2767#endif
David Aschere2b4b322004-02-18 05:59:53 +00002768 return NULL;
2769 }
2770 }
2771 Py_INCREF(Py_None);
2772 return Py_None;
2773}
Barry Warsawfa701a81997-01-16 00:15:11 +00002774
Martin v. Löwisffad6332002-11-26 09:28:05 +00002775static PyObject *
2776Tkapp_WantObjects(PyObject *self, PyObject *args)
2777{
2778
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002779 int wantobjects = -1;
2780 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002781 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002782 if (wantobjects == -1)
2783 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002784 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002785
2786 Py_INCREF(Py_None);
2787 return Py_None;
2788}
2789
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002790static PyObject *
2791Tkapp_WillDispatch(PyObject *self, PyObject *args)
2792{
2793
2794 ((TkappObject*)self)->dispatching = 1;
2795
2796 Py_INCREF(Py_None);
2797 return Py_None;
2798}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002799
Barry Warsawfa701a81997-01-16 00:15:11 +00002800
Guido van Rossum18468821994-06-20 07:49:28 +00002801/**** Tkapp Method List ****/
2802
2803static PyMethodDef Tkapp_methods[] =
2804{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002805 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002806 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Neal Norwitze2e447b2007-05-22 07:16:10 +00002807 {"call", Tkapp_Call, METH_VARARGS},
2808 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002809 {"eval", Tkapp_Eval, METH_VARARGS},
2810 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2811 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2812 {"record", Tkapp_Record, METH_VARARGS},
2813 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2814 {"setvar", Tkapp_SetVar, METH_VARARGS},
2815 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2816 {"getvar", Tkapp_GetVar, METH_VARARGS},
2817 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2818 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2819 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2820 {"getint", Tkapp_GetInt, METH_VARARGS},
2821 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2822 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2823 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2824 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2825 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2826 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2827 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2828 {"split", Tkapp_Split, METH_VARARGS},
Neal Norwitze2e447b2007-05-22 07:16:10 +00002829 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002830 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2831 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002832#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002833 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2834 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002835#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002836 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2837 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2838 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2839 {"quit", Tkapp_Quit, METH_VARARGS},
2840 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002841 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002842 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002843};
2844
Barry Warsawfa701a81997-01-16 00:15:11 +00002845
2846
Guido van Rossum18468821994-06-20 07:49:28 +00002847/**** Tkapp Type Methods ****/
2848
2849static void
Fred Drake509d79a2000-07-08 04:04:38 +00002850Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002851{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002852 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002853 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002854 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002855 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002856 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002857 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002858}
2859
2860static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002861Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002862{
Guido van Rossum35d43371997-08-02 00:09:09 +00002863 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002864}
2865
2866static PyTypeObject Tkapp_Type =
2867{
Martin v. Löwis68192102007-07-21 06:55:02 +00002868 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002869 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002870 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002871 0, /*tp_itemsize */
2872 Tkapp_Dealloc, /*tp_dealloc */
2873 0, /*tp_print */
2874 Tkapp_GetAttr, /*tp_getattr */
2875 0, /*tp_setattr */
2876 0, /*tp_compare */
2877 0, /*tp_repr */
2878 0, /*tp_as_number */
2879 0, /*tp_as_sequence */
2880 0, /*tp_as_mapping */
2881 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002882};
2883
Barry Warsawfa701a81997-01-16 00:15:11 +00002884
2885
Guido van Rossum18468821994-06-20 07:49:28 +00002886/**** Tkinter Module ****/
2887
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002888typedef struct {
2889 PyObject* tuple;
2890 int size; /* current size */
2891 int maxsize; /* allocated size */
2892} FlattenContext;
2893
2894static int
2895_bump(FlattenContext* context, int size)
2896{
Guido van Rossum2834b972000-10-06 16:58:26 +00002897 /* expand tuple to hold (at least) size new items.
2898 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002899
2900 int maxsize = context->maxsize * 2;
2901
2902 if (maxsize < context->size + size)
2903 maxsize = context->size + size;
2904
2905 context->maxsize = maxsize;
2906
Tim Peters4324aa32001-05-28 22:30:08 +00002907 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002908}
2909
2910static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002911_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002912{
2913 /* add tuple or list to argument tuple (recursively) */
2914
2915 int i, size;
2916
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002917 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002918 PyErr_SetString(PyExc_ValueError,
2919 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002920 return 0;
2921 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002922 size = PyList_GET_SIZE(item);
2923 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002924 if (context->size + size > context->maxsize &&
2925 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002926 return 0;
2927 /* copy items to output tuple */
2928 for (i = 0; i < size; i++) {
2929 PyObject *o = PyList_GET_ITEM(item, i);
2930 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002931 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002932 return 0;
2933 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002934 if (context->size + 1 > context->maxsize &&
2935 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002936 return 0;
2937 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002938 PyTuple_SET_ITEM(context->tuple,
2939 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002940 }
2941 }
2942 } else if (PyTuple_Check(item)) {
2943 /* same, for tuples */
2944 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002945 if (context->size + size > context->maxsize &&
2946 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002947 return 0;
2948 for (i = 0; i < size; i++) {
2949 PyObject *o = PyTuple_GET_ITEM(item, i);
2950 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002951 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002952 return 0;
2953 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002954 if (context->size + 1 > context->maxsize &&
2955 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002956 return 0;
2957 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002958 PyTuple_SET_ITEM(context->tuple,
2959 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002960 }
2961 }
2962 } else {
2963 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2964 return 0;
2965 }
2966 return 1;
2967}
2968
2969static PyObject *
2970Tkinter_Flatten(PyObject* self, PyObject* args)
2971{
2972 FlattenContext context;
2973 PyObject* item;
2974
2975 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2976 return NULL;
2977
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002978 context.maxsize = PySequence_Size(item);
Benjamin Petersonb3619be2009-01-30 02:24:39 +00002979 if (context.maxsize < 0)
2980 return NULL;
2981 if (context.maxsize == 0)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002982 return PyTuple_New(0);
2983
2984 context.tuple = PyTuple_New(context.maxsize);
2985 if (!context.tuple)
2986 return NULL;
2987
2988 context.size = 0;
2989
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002990 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002991 return NULL;
2992
Tim Peters4324aa32001-05-28 22:30:08 +00002993 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002994 return NULL;
2995
2996 return context.tuple;
2997}
2998
Guido van Rossum18468821994-06-20 07:49:28 +00002999static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003000Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00003001{
Barry Warsawfa701a81997-01-16 00:15:11 +00003002 char *screenName = NULL;
3003 char *baseName = NULL;
3004 char *className = NULL;
3005 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00003006 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00003007 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00003008 int sync = 0; /* pass -sync to wish */
3009 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00003010
Guido van Rossum35d43371997-08-02 00:09:09 +00003011 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00003012 if (baseName != NULL)
3013 baseName++;
3014 else
3015 baseName = Py_GetProgramName();
3016 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00003017
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00003018 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00003019 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00003020 &interactive, &wantobjects, &wantTk,
3021 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00003022 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00003023
Barry Warsawfa701a81997-01-16 00:15:11 +00003024 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00003025 interactive, wantobjects, wantTk,
3026 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00003027}
3028
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003029static PyObject *
3030Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
3031{
3032 int new_val;
3033 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
3034 return NULL;
3035 if (new_val < 0) {
3036 PyErr_SetString(PyExc_ValueError,
3037 "busywaitinterval must be >= 0");
3038 return NULL;
3039 }
3040 Tkinter_busywaitinterval = new_val;
3041 Py_INCREF(Py_None);
3042 return Py_None;
3043}
3044
3045static char setbusywaitinterval_doc[] =
3046"setbusywaitinterval(n) -> None\n\
3047\n\
3048Set the busy-wait interval in milliseconds between successive\n\
3049calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
3050It should be set to a divisor of the maximum time between\n\
3051frames in an animation.";
3052
3053static PyObject *
3054Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
3055{
3056 return PyInt_FromLong(Tkinter_busywaitinterval);
3057}
3058
3059static char getbusywaitinterval_doc[] =
3060"getbusywaitinterval() -> int\n\
3061\n\
3062Return the current busy-wait interval between successive\n\
3063calls to Tcl_DoOneEvent in a threaded Python interpreter.";
3064
Guido van Rossum18468821994-06-20 07:49:28 +00003065static PyMethodDef moduleMethods[] =
3066{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003067 {"_flatten", Tkinter_Flatten, METH_VARARGS},
3068 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00003069#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003070 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
3071 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00003072#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003073 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
3074 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
3075 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
3076 {"quit", Tkapp_Quit, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003077 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
3078 setbusywaitinterval_doc},
3079 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
3080 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00003081 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00003082};
3083
Guido van Rossum7bf15641998-05-22 18:28:17 +00003084#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003085
3086static int stdin_ready = 0;
3087
Guido van Rossumad4db171998-06-13 13:56:28 +00003088#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00003089static void
Fred Drake509d79a2000-07-08 04:04:38 +00003090MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003091{
3092 stdin_ready = 1;
3093}
Guido van Rossumad4db171998-06-13 13:56:28 +00003094#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003095
Martin v. Löwisa9656492003-03-30 08:44:58 +00003096#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003097static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00003098#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00003099
Guido van Rossum18468821994-06-20 07:49:28 +00003100static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003101EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003102{
Guido van Rossumad4db171998-06-13 13:56:28 +00003103#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00003104 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00003105#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003106#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003107 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003108#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003109 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00003110 errorInCmd = 0;
3111#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00003112 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003113 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00003114#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003115 while (!errorInCmd && !stdin_ready) {
3116 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00003117#ifdef MS_WINDOWS
3118 if (_kbhit()) {
3119 stdin_ready = 1;
3120 break;
3121 }
3122#endif
3123#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00003124 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003125 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00003126 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003127
Guido van Rossum00d93061998-05-28 23:06:38 +00003128 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003129
3130 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003131 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00003132 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003133 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00003134 Py_END_ALLOW_THREADS
3135#else
3136 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003137#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003138
3139 if (result < 0)
3140 break;
3141 }
Guido van Rossumad4db171998-06-13 13:56:28 +00003142#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00003143 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00003144#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003145 if (errorInCmd) {
3146 errorInCmd = 0;
3147 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3148 excInCmd = valInCmd = trbInCmd = NULL;
3149 PyErr_Print();
3150 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003151#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003152 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003153#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003154 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00003155}
Guido van Rossum18468821994-06-20 07:49:28 +00003156
Guido van Rossum00d93061998-05-28 23:06:38 +00003157#endif
3158
Guido van Rossum7bf15641998-05-22 18:28:17 +00003159static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003160EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003161{
Guido van Rossum00d93061998-05-28 23:06:38 +00003162#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003163 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003164#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003165 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003166#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003167 PyOS_InputHook = EventHook;
3168 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003169#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003170}
3171
3172static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003173DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003174{
Guido van Rossum00d93061998-05-28 23:06:38 +00003175#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003176 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3177 PyOS_InputHook = NULL;
3178 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003179#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003180}
3181
Barry Warsawfa701a81997-01-16 00:15:11 +00003182
3183/* all errors will be checked in one fell swoop in init_tkinter() */
3184static void
Fred Drake509d79a2000-07-08 04:04:38 +00003185ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003186{
3187 PyObject *v = PyInt_FromLong(val);
3188 if (v) {
3189 PyDict_SetItemString(d, name, v);
3190 Py_DECREF(v);
3191 }
3192}
3193static void
Fred Drake509d79a2000-07-08 04:04:38 +00003194ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003195{
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003196 PyObject *v = PyString_FromString(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003197 if (v) {
3198 PyDict_SetItemString(d, name, v);
3199 Py_DECREF(v);
3200 }
3201}
3202
3203
Mark Hammond62b1ab12002-07-23 06:31:15 +00003204PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003205init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003206{
Barry Warsawfa701a81997-01-16 00:15:11 +00003207 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00003208
Christian Heimese93237d2007-12-19 02:37:44 +00003209 Py_TYPE(&Tkapp_Type) = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00003210
3211#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003212 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003213#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003214
Barry Warsawfa701a81997-01-16 00:15:11 +00003215 m = Py_InitModule("_tkinter", moduleMethods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003216 if (m == NULL)
3217 return;
Guido van Rossum18468821994-06-20 07:49:28 +00003218
Barry Warsawfa701a81997-01-16 00:15:11 +00003219 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003220 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003221 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003222
Guido van Rossum35d43371997-08-02 00:09:09 +00003223 ins_long(d, "READABLE", TCL_READABLE);
3224 ins_long(d, "WRITABLE", TCL_WRITABLE);
3225 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3226 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3227 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3228 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3229 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3230 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3231 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003232 ins_string(d, "TK_VERSION", TK_VERSION);
3233 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003234
Guido van Rossum83551bf1997-09-13 00:44:23 +00003235 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003236
Christian Heimese93237d2007-12-19 02:37:44 +00003237 Py_TYPE(&Tktt_Type) = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003238 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3239
Christian Heimese93237d2007-12-19 02:37:44 +00003240 Py_TYPE(&PyTclObject_Type) = &PyType_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003241 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003242
3243#ifdef TK_AQUA
3244 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3245 * start waking up. Note that Tcl_FindExecutable will do this, this
3246 * code must be above it! The original warning from
3247 * tkMacOSXAppInit.c is copied below.
3248 *
3249 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3250 * Tcl interpreter for now. It probably should work to do this
3251 * in the other order, but for now it doesn't seem to.
3252 *
3253 */
3254 Tk_MacOSXSetupTkNotifier();
3255#endif
3256
3257
Guido van Rossume187b0e2000-03-27 21:46:29 +00003258 /* This helps the dynamic loader; in Unicode aware Tcl versions
3259 it also helps Tcl find its encodings. */
3260 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00003261
Barry Warsawfa701a81997-01-16 00:15:11 +00003262 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003263 return;
3264
Guido van Rossum43ff8681998-07-14 18:02:13 +00003265#if 0
3266 /* This was not a good idea; through <Destroy> bindings,
3267 Tcl_Finalize() may invoke Python code but at that point the
3268 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003269 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003270#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003271
Guido van Rossum18468821994-06-20 07:49:28 +00003272}