blob: 1f5a470c9e89e7ab7bfda05352f821be860fcac2 [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 Polo491aee22009-02-06 23:16:11 +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
Guilherme Polob681df42009-02-09 22:33:59 +000036#include "tkinter.h"
37
Martin v. Löwis39195712003-01-04 00:33:13 +000038/* Allow using this code in Python 2.[12] */
39#ifndef PyDoc_STRVAR
Martin v. Löwiscd9a8b62003-01-21 21:52:57 +000040#define PyDoc_STRVAR(name,str) static char name[] = str
Martin v. Löwis39195712003-01-04 00:33:13 +000041#endif
42
43#ifndef PyMODINIT_FUNC
Martin v. Löwis3a57d9d2003-01-04 08:54:59 +000044#define PyMODINIT_FUNC void
Martin v. Löwis39195712003-01-04 00:33:13 +000045#endif
46
Martin v. Löwis52ae6f62003-03-30 08:26:04 +000047#ifndef PyBool_Check
48#define PyBool_Check(o) 0
Christian Heimes217cfd12007-12-02 14:31:20 +000049#define PyBool_FromLong PyLong_FromLong
Martin v. Löwis52ae6f62003-03-30 08:26:04 +000050#endif
51
Martin v. Löwis71e25a02002-10-01 18:08:06 +000052/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
53 making _tkinter correct for this API means to break earlier
54 versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
55 earlier versions. Once Tcl releases before 8.4 don't need to be supported
56 anymore, this should go. */
57#define USE_COMPAT_CONST
58
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000059/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
60 it always; if Tcl is not threaded, the thread functions in
61 Tcl are empty. */
62#define TCL_THREADS
63
Jack Jansencb852442001-12-09 23:15:56 +000064#ifdef TK_FRAMEWORK
65#include <Tcl/tcl.h>
66#include <Tk/tk.h>
67#else
Guido van Rossum18468821994-06-20 07:49:28 +000068#include <tcl.h>
69#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000070#endif
Guido van Rossum18468821994-06-20 07:49:28 +000071
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 Polob681df42009-02-09 22:33:59 +000079#if TK_VERSION_HEX < 0x08020002
Martin v. Löwis6bfa2e62002-10-01 17:48:31 +000080#error "Tk older than 8.2 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000081#endif
82
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000083/* Unicode conversion assumes that Tcl_UniChar is two bytes.
84 We cannot test this directly, so we test UTF-8 size instead,
85 expecting that TCL_UTF_MAX is changed if Tcl ever supports
Guido van Rossum82c0dfa2007-11-21 20:09:18 +000086 either UTF-16 or UCS-4.
87 Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for
Martin v. Löwis6f29ff32003-04-16 20:34:55 +000088 Tcl_Unichar. This is also ok as long as Python uses UCS-4,
89 as well.
90*/
91#if TCL_UTF_MAX != 3 && !(defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==6)
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000092#error "unsupported Tcl configuration"
93#endif
94
Jack Janseneddc1442003-11-20 01:44:59 +000095#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
Guido van Rossum0d2390c1997-08-14 19:57:07 +000096#define HAVE_CREATEFILEHANDLER
97#endif
98
Guido van Rossum00d93061998-05-28 23:06:38 +000099#ifdef HAVE_CREATEFILEHANDLER
100
Neal Norwitzd948a432006-01-08 01:08:55 +0000101/* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere
102 with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */
103#ifndef TCL_UNIX_FD
104# ifdef TCL_WIN_SOCKET
105# define TCL_UNIX_FD (! TCL_WIN_SOCKET)
106# else
107# define TCL_UNIX_FD 1
108# endif
109#endif
110
Guido van Rossum00d93061998-05-28 23:06:38 +0000111/* Tcl_CreateFileHandler() changed several times; these macros deal with the
112 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
113 Unix, only because Jack added it back); when available on Windows, it only
114 applies to sockets. */
115
Guido van Rossum7bf15641998-05-22 18:28:17 +0000116#ifdef MS_WINDOWS
117#define FHANDLETYPE TCL_WIN_SOCKET
118#else
119#define FHANDLETYPE TCL_UNIX_FD
120#endif
121
Guido van Rossum00d93061998-05-28 23:06:38 +0000122/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
123 which uses this to handle Tcl events while the user is typing commands. */
124
125#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000126#define WAIT_FOR_STDIN
127#endif
128
Guido van Rossum00d93061998-05-28 23:06:38 +0000129#endif /* HAVE_CREATEFILEHANDLER */
130
Guido van Rossumad4db171998-06-13 13:56:28 +0000131#ifdef MS_WINDOWS
132#include <conio.h>
133#define WAIT_FOR_STDIN
134#endif
135
Guido van Rossum00d93061998-05-28 23:06:38 +0000136#ifdef WITH_THREAD
137
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000138/* The threading situation is complicated. Tcl is not thread-safe, except
139 when configured with --enable-threads.
Guido van Rossum00d93061998-05-28 23:06:38 +0000140 So we need to use a lock around all uses of Tcl. Previously, the Python
141 interpreter lock was used for this. However, this causes problems when
142 other Python threads need to run while Tcl is blocked waiting for events.
143
144 To solve this problem, a separate lock for Tcl is introduced. Holding it
145 is incompatible with holding Python's interpreter lock. The following four
146 macros manipulate both locks together.
147
148 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
149 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
150 that could call an event handler, or otherwise affect the state of a Tcl
151 interpreter. These assume that the surrounding code has the Python
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000152 interpreter lock; inside the brackets, the Python interpreter lock has been
Guido van Rossum00d93061998-05-28 23:06:38 +0000153 released and the lock for Tcl has been acquired.
154
Guido van Rossum5e977831998-06-15 14:03:52 +0000155 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
156 (For example, when transferring data from the Tcl interpreter result to a
157 Python string object.) This can be done by using different macros to close
158 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
159 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
160 releases the Tcl lock.
161
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000162 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000163 handlers when the handler needs to use Python. Such event handlers are
164 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000165 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000166 the Python interpreter lock, restoring the appropriate thread state, and
167 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
168 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000169 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000170
171 These locks expand to several statements and brackets; they should not be
172 used in branches of if statements and the like.
173
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000174 If Tcl is threaded, this approach won't work anymore. The Tcl interpreter is
175 only valid in the thread that created it, and all Tk activity must happen in this
176 thread, also. That means that the mainloop must be invoked in the thread that
177 created the interpreter. Invoking commands from other threads is possible;
178 _tkinter will queue an event for the interpreter thread, which will then
179 execute the command and pass back the result. If the main thread is not in the
180 mainloop, and invoking commands causes an exception; if the main loop is running
181 but not processing events, the command invocation will block.
182
183 In addition, for a threaded Tcl, a single global tcl_tstate won't be sufficient
184 anymore, since multiple Tcl interpreters may simultaneously dispatch in different
185 threads. So we use the Tcl TLS API.
186
Guido van Rossum00d93061998-05-28 23:06:38 +0000187*/
188
Guido van Rossum65d5b571998-12-21 19:32:43 +0000189static PyThread_type_lock tcl_lock = 0;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000190
191#ifdef TCL_THREADS
192static Tcl_ThreadDataKey state_key;
193typedef PyThreadState *ThreadSpecificData;
194#define tcl_tstate (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*)))
195#else
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000196static PyThreadState *tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000197#endif
Guido van Rossum00d93061998-05-28 23:06:38 +0000198
199#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000200 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000201 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000202
203#define LEAVE_TCL \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000204 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000205
Guido van Rossum62320c91998-06-15 04:36:09 +0000206#define ENTER_OVERLAP \
207 Py_END_ALLOW_THREADS
208
209#define LEAVE_OVERLAP_TCL \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000210 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000211
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000212#define ENTER_PYTHON \
213 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000214 if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000215
216#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000217 { PyThreadState *tstate = PyEval_SaveThread(); \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000218 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
219
220#define CHECK_TCL_APPARTMENT \
221 if (((TkappObject *)self)->threaded && \
222 ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
223 PyErr_SetString(PyExc_RuntimeError, "Calling Tcl from different appartment"); \
224 return 0; \
225 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000226
227#else
228
229#define ENTER_TCL
230#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000231#define ENTER_OVERLAP
232#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000233#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000234#define LEAVE_PYTHON
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000235#define CHECK_TCL_APPARTMENT
Guido van Rossum00d93061998-05-28 23:06:38 +0000236
237#endif
238
Guido van Rossum97867b21996-08-08 19:09:53 +0000239#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000240#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000241#endif
242
Guido van Rossum18468821994-06-20 07:49:28 +0000243/**** Tkapp Object Declaration ****/
244
Jeremy Hylton938ace62002-07-17 16:30:39 +0000245static PyTypeObject Tkapp_Type;
Guido van Rossum18468821994-06-20 07:49:28 +0000246
Guido van Rossum00d93061998-05-28 23:06:38 +0000247typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000248 PyObject_HEAD
249 Tcl_Interp *interp;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000250 int wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000251 int threaded; /* True if tcl_platform[threaded] */
252 Tcl_ThreadId thread_id;
253 int dispatching;
254 /* We cannot include tclInt.h, as this is internal.
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000255 So we cache interesting types here. */
256 Tcl_ObjType *BooleanType;
257 Tcl_ObjType *ByteArrayType;
258 Tcl_ObjType *DoubleType;
259 Tcl_ObjType *IntType;
260 Tcl_ObjType *ListType;
261 Tcl_ObjType *ProcBodyType;
262 Tcl_ObjType *StringType;
Guido van Rossum00d93061998-05-28 23:06:38 +0000263} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000264
Christian Heimes90aa7642007-12-19 02:45:37 +0000265#define Tkapp_Check(v) (Py_TYPE(v) == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000266#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000267#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000268
Guido van Rossum35d43371997-08-02 00:09:09 +0000269#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Christian Heimes90aa7642007-12-19 02:45:37 +0000270(void *) v, Py_REFCNT(v)))
Guido van Rossum18468821994-06-20 07:49:28 +0000271
Barry Warsawfa701a81997-01-16 00:15:11 +0000272
273
Guido van Rossum18468821994-06-20 07:49:28 +0000274/**** Error Handling ****/
275
276static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000277static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000278static int errorInCmd = 0;
279static PyObject *excInCmd;
280static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000282
Guilherme Polob681df42009-02-09 22:33:59 +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{
Christian Heimes72b710a2008-05-26 13:28:38 +0000341 if (PyBytes_Check(value))
342 return PyBytes_AsString(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000343 else if (PyUnicode_Check(value)) {
344 PyObject *v = PyUnicode_AsUTF8String(value);
345 if (v == NULL)
346 return NULL;
347 if (PyList_Append(tmp, v) != 0) {
348 Py_DECREF(v);
349 return NULL;
350 }
351 Py_DECREF(v);
Christian Heimes72b710a2008-05-26 13:28:38 +0000352 return PyBytes_AsString(v);
Guido van Rossum2834b972000-10-06 16:58:26 +0000353 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000354 else {
355 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000356 if (v == NULL)
357 return NULL;
358 if (PyList_Append(tmp, v) != 0) {
359 Py_DECREF(v);
360 return NULL;
361 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000362 Py_DECREF(v);
Christian Heimes72b710a2008-05-26 13:28:38 +0000363 return PyBytes_AsString(v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000364 }
Guido van Rossum18468821994-06-20 07:49:28 +0000365}
366
Barry Warsawfa701a81997-01-16 00:15:11 +0000367
368
Guido van Rossum18468821994-06-20 07:49:28 +0000369#define ARGSZ 64
370
371static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000372Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000373{
Barry Warsawfa701a81997-01-16 00:15:11 +0000374 PyObject *tmp = NULL;
375 char *argvStore[ARGSZ];
376 char **argv = NULL;
377 int fvStore[ARGSZ];
378 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000379 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000380 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000381
Barry Warsawfa701a81997-01-16 00:15:11 +0000382 if (!(tmp = PyList_New(0)))
383 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000384
Barry Warsawfa701a81997-01-16 00:15:11 +0000385 argv = argvStore;
386 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000387
Barry Warsawfa701a81997-01-16 00:15:11 +0000388 if (args == NULL)
389 argc = 0;
390
391 else if (!PyTuple_Check(args)) {
392 argc = 1;
393 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000394 if (!(argv[0] = AsString(args, tmp)))
395 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000396 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000397 else {
398 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000399
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000401 argv = (char **)ckalloc(argc * sizeof(char *));
402 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000403 if (argv == NULL || fv == NULL) {
404 PyErr_NoMemory();
405 goto finally;
406 }
407 }
408
409 for (i = 0; i < argc; i++) {
410 PyObject *v = PyTuple_GetItem(args, i);
411 if (PyTuple_Check(v)) {
412 fv[i] = 1;
413 if (!(argv[i] = Merge(v)))
414 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000415 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000416 }
417 else if (v == Py_None) {
418 argc = i;
419 break;
420 }
421 else {
422 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000423 if (!(argv[i] = AsString(v, tmp)))
424 goto finally;
425 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000426 }
427 }
Guido van Rossum18468821994-06-20 07:49:28 +0000428 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000429 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000430 if (res == NULL)
431 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000432
Barry Warsawfa701a81997-01-16 00:15:11 +0000433 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000434 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000435 if (fv[i]) {
436 ckfree(argv[i]);
437 }
438 if (argv != argvStore)
439 ckfree(FREECAST argv);
440 if (fv != fvStore)
441 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000442
Barry Warsawfa701a81997-01-16 00:15:11 +0000443 Py_DECREF(tmp);
444 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000445}
446
Barry Warsawfa701a81997-01-16 00:15:11 +0000447
448
Guido van Rossum18468821994-06-20 07:49:28 +0000449static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000450Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000451{
Barry Warsawfa701a81997-01-16 00:15:11 +0000452 int argc;
453 char **argv;
454 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000455
Barry Warsawfa701a81997-01-16 00:15:11 +0000456 if (list == NULL) {
457 Py_INCREF(Py_None);
458 return Py_None;
459 }
Guido van Rossum18468821994-06-20 07:49:28 +0000460
Guido van Rossum00d93061998-05-28 23:06:38 +0000461 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000462 /* Not a list.
463 * Could be a quoted string containing funnies, e.g. {"}.
464 * Return the string itself.
465 */
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000466 return PyUnicode_FromString(list);
Barry Warsawfa701a81997-01-16 00:15:11 +0000467 }
Guido van Rossum18468821994-06-20 07:49:28 +0000468
Barry Warsawfa701a81997-01-16 00:15:11 +0000469 if (argc == 0)
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000470 v = PyUnicode_FromString("");
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 else if (argc == 1)
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000472 v = PyUnicode_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000473 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000474 int i;
475 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000476
Barry Warsawfa701a81997-01-16 00:15:11 +0000477 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000478 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000479 Py_DECREF(v);
480 v = NULL;
481 break;
482 }
483 PyTuple_SetItem(v, i, w);
484 }
485 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000486 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000487 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000488}
489
Martin v. Löwisffad6332002-11-26 09:28:05 +0000490/* In some cases, Tcl will still return strings that are supposed to be
491 lists. SplitObj walks through a nested tuple, finding string objects that
492 need to be split. */
493
Martin v. Löwis59683e82008-06-13 07:50:45 +0000494static PyObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000495SplitObj(PyObject *arg)
496{
497 if (PyTuple_Check(arg)) {
498 int i, size;
499 PyObject *elem, *newelem, *result;
500
501 size = PyTuple_Size(arg);
502 result = NULL;
503 /* Recursively invoke SplitObj for all tuple items.
504 If this does not return a new object, no action is
505 needed. */
506 for(i = 0; i < size; i++) {
507 elem = PyTuple_GetItem(arg, i);
508 newelem = SplitObj(elem);
509 if (!newelem) {
510 Py_XDECREF(result);
511 return NULL;
512 }
513 if (!result) {
514 int k;
515 if (newelem == elem) {
516 Py_DECREF(newelem);
517 continue;
518 }
519 result = PyTuple_New(size);
520 if (!result)
521 return NULL;
522 for(k = 0; k < i; k++) {
523 elem = PyTuple_GetItem(arg, k);
524 Py_INCREF(elem);
525 PyTuple_SetItem(result, k, elem);
526 }
527 }
528 PyTuple_SetItem(result, i, newelem);
529 }
530 if (result)
531 return result;
532 /* Fall through, returning arg. */
533 }
Christian Heimes72b710a2008-05-26 13:28:38 +0000534 else if (PyBytes_Check(arg)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000535 int argc;
536 char **argv;
Christian Heimes72b710a2008-05-26 13:28:38 +0000537 char *list = PyBytes_AsString(arg);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000538
539 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
540 Py_INCREF(arg);
541 return arg;
542 }
543 Tcl_Free(FREECAST argv);
544 if (argc > 1)
Christian Heimes72b710a2008-05-26 13:28:38 +0000545 return Split(PyBytes_AsString(arg));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000546 /* Fall through, returning arg. */
547 }
548 Py_INCREF(arg);
549 return arg;
550}
Barry Warsawfa701a81997-01-16 00:15:11 +0000551
552
Guido van Rossum18468821994-06-20 07:49:28 +0000553/**** Tkapp Object ****/
554
555#ifndef WITH_APPINIT
556int
Fred Drake509d79a2000-07-08 04:04:38 +0000557Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000558{
David Aschere2b4b322004-02-18 05:59:53 +0000559 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000560
Barry Warsawfa701a81997-01-16 00:15:11 +0000561 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000562 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000563 return TCL_ERROR;
564 }
Guilherme Polob681df42009-02-09 22:33:59 +0000565
566 _tkinter_skip_tk_init = Tcl_GetVar(interp,
567 "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
568 if (_tkinter_skip_tk_init != NULL &&
569 strcmp(_tkinter_skip_tk_init, "1") == 0) {
570 return TCL_OK;
Barry Warsawfa701a81997-01-16 00:15:11 +0000571 }
Guilherme Polob681df42009-02-09 22:33:59 +0000572
573#ifdef TKINTER_PROTECT_LOADTK
574 if (tk_load_failed) {
575 PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG);
576 return TCL_ERROR;
577 }
578#endif
579
580 if (Tk_Init(interp) == TCL_ERROR) {
581#ifdef TKINTER_PROTECT_LOADTK
582 tk_load_failed = 1;
583#endif
584 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
585 return TCL_ERROR;
586 }
587
Barry Warsawfa701a81997-01-16 00:15:11 +0000588 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000589}
590#endif /* !WITH_APPINIT */
591
Guido van Rossum18468821994-06-20 07:49:28 +0000592
Barry Warsawfa701a81997-01-16 00:15:11 +0000593
594
595/* Initialize the Tk application; see the `main' function in
596 * `tkMain.c'.
597 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000598
Thomas Wouters58d05102000-07-24 14:43:35 +0000599static void EnableEventHook(void); /* Forward */
600static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000601
Barry Warsawfa701a81997-01-16 00:15:11 +0000602static TkappObject *
Martin v. Löwisb9279bc2008-04-05 19:47:23 +0000603Tkapp_New(char *screenName, char *className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000604 int interactive, int wantobjects, int wantTk, int sync, char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000605{
606 TkappObject *v;
607 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000608
Guido van Rossumb18618d2000-05-03 23:44:39 +0000609 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000610 if (v == NULL)
611 return NULL;
612
613 v->interp = Tcl_CreateInterp();
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000614 v->wantobjects = wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000615 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
616 TCL_GLOBAL_ONLY) != NULL;
617 v->thread_id = Tcl_GetCurrentThread();
618 v->dispatching = 0;
619
620#ifndef TCL_THREADS
621 if (v->threaded) {
622 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
623 Py_DECREF(v);
624 return 0;
625 }
626#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000627#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000628 if (v->threaded && tcl_lock) {
629 /* If Tcl is threaded, we don't need the lock. */
630 PyThread_free_lock(tcl_lock);
631 tcl_lock = NULL;
632 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000633#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000634
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000635 v->BooleanType = Tcl_GetObjType("boolean");
636 v->ByteArrayType = Tcl_GetObjType("bytearray");
637 v->DoubleType = Tcl_GetObjType("double");
638 v->IntType = Tcl_GetObjType("int");
639 v->ListType = Tcl_GetObjType("list");
640 v->ProcBodyType = Tcl_GetObjType("procbody");
641 v->StringType = Tcl_GetObjType("string");
642
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000643 /* Delete the 'exit' command, which can screw things up */
644 Tcl_DeleteCommand(v->interp, "exit");
645
Barry Warsawfa701a81997-01-16 00:15:11 +0000646 if (screenName != NULL)
647 Tcl_SetVar2(v->interp, "env", "DISPLAY",
648 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000649
Barry Warsawfa701a81997-01-16 00:15:11 +0000650 if (interactive)
651 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
652 else
653 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000654
Barry Warsawfa701a81997-01-16 00:15:11 +0000655 /* This is used to get the application class for Tk 4.1 and up */
656 argv0 = (char*)ckalloc(strlen(className) + 1);
657 if (!argv0) {
658 PyErr_NoMemory();
659 Py_DECREF(v);
660 return NULL;
661 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000662
Barry Warsawfa701a81997-01-16 00:15:11 +0000663 strcpy(argv0, className);
Neal Norwitz9dbc7dd2005-12-19 06:08:59 +0000664 if (isupper(Py_CHARMASK(argv0[0])))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000665 argv0[0] = tolower(Py_CHARMASK(argv0[0]));
Barry Warsawfa701a81997-01-16 00:15:11 +0000666 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
667 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000668
David Aschere2b4b322004-02-18 05:59:53 +0000669 if (! wantTk) {
Guilherme Polob681df42009-02-09 22:33:59 +0000670 Tcl_SetVar(v->interp,
671 "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
David Aschere2b4b322004-02-18 05:59:53 +0000672 }
Guilherme Polob681df42009-02-09 22:33:59 +0000673#ifdef TKINTER_PROTECT_LOADTK
674 else if (tk_load_failed) {
675 Tcl_SetVar(v->interp,
676 "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY);
677 }
678#endif
David Aschere2b4b322004-02-18 05:59:53 +0000679
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000680 /* some initial arguments need to be in argv */
681 if (sync || use) {
Tim Peters51fa3b72004-08-04 02:16:48 +0000682 char *args;
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000683 int len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000684
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000685 if (sync)
686 len += sizeof "-sync";
687 if (use)
688 len += strlen(use) + sizeof "-use ";
689
Tim Peters51fa3b72004-08-04 02:16:48 +0000690 args = (char*)ckalloc(len);
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000691 if (!args) {
692 PyErr_NoMemory();
693 Py_DECREF(v);
694 return NULL;
695 }
696
697 args[0] = '\0';
698 if (sync)
699 strcat(args, "-sync");
700 if (use) {
701 if (sync)
702 strcat(args, " ");
703 strcat(args, "-use ");
704 strcat(args, use);
705 }
706
707 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
708 ckfree(args);
709 }
710
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000711 if (Tcl_AppInit(v->interp) != TCL_OK) {
712 PyObject *result = Tkinter_Error((PyObject *)v);
Guilherme Polob681df42009-02-09 22:33:59 +0000713#ifdef TKINTER_PROTECT_LOADTK
714 if (wantTk) {
715 const char *_tkinter_tk_failed;
716 _tkinter_tk_failed = Tcl_GetVar(v->interp,
717 "_tkinter_tk_failed", TCL_GLOBAL_ONLY);
718
719 if ( _tkinter_tk_failed != NULL &&
720 strcmp(_tkinter_tk_failed, "1") == 0) {
721 tk_load_failed = 1;
722 }
723 }
724#endif
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000725 Py_DECREF((PyObject *)v);
726 return (TkappObject *)result;
727 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000728
Guido van Rossum7bf15641998-05-22 18:28:17 +0000729 EnableEventHook();
730
Barry Warsawfa701a81997-01-16 00:15:11 +0000731 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000732}
733
Barry Warsawfa701a81997-01-16 00:15:11 +0000734
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000735static void
736Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
737 Tcl_Condition *cond, Tcl_Mutex *mutex)
738{
739 Py_BEGIN_ALLOW_THREADS;
740 Tcl_MutexLock(mutex);
741 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
742 Tcl_ThreadAlert(self->thread_id);
743 Tcl_ConditionWait(cond, mutex, NULL);
744 Tcl_MutexUnlock(mutex);
745 Py_END_ALLOW_THREADS
746}
747
Barry Warsawfa701a81997-01-16 00:15:11 +0000748
Guido van Rossum18468821994-06-20 07:49:28 +0000749/** Tcl Eval **/
750
Martin v. Löwisffad6332002-11-26 09:28:05 +0000751typedef struct {
752 PyObject_HEAD
753 Tcl_Obj *value;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000754 PyObject *string; /* This cannot cause cycles. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000755} PyTclObject;
756
Neal Norwitz227b5332006-03-22 09:28:35 +0000757static PyTypeObject PyTclObject_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000758#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
759
760static PyObject *
761newPyTclObject(Tcl_Obj *arg)
762{
763 PyTclObject *self;
764 self = PyObject_New(PyTclObject, &PyTclObject_Type);
765 if (self == NULL)
766 return NULL;
767 Tcl_IncrRefCount(arg);
768 self->value = arg;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000769 self->string = NULL;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000770 return (PyObject*)self;
771}
772
773static void
774PyTclObject_dealloc(PyTclObject *self)
775{
776 Tcl_DecrRefCount(self->value);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000777 Py_XDECREF(self->string);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000778 PyObject_Del(self);
779}
780
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000781static char*
782PyTclObject_TclString(PyObject *self)
783{
784 return Tcl_GetString(((PyTclObject*)self)->value);
785}
786
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000787/* Like _str, but create Unicode if necessary. */
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000788PyDoc_STRVAR(PyTclObject_string__doc__,
Christian Heimesb2b62622007-11-22 05:56:35 +0000789"the string representation of this object, either as str or bytes");
Martin v. Löwis39195712003-01-04 00:33:13 +0000790
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000791static PyObject *
792PyTclObject_string(PyTclObject *self, void *ignored)
793{
794 char *s;
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000795 int len;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000796 if (!self->string) {
797 s = Tcl_GetStringFromObj(self->value, &len);
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000798 self->string = PyUnicode_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000799 if (!self->string)
800 return NULL;
801 }
802 Py_INCREF(self->string);
803 return self->string;
804}
805
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000806static PyObject *
Walter Dörwald6720d912007-07-12 12:12:25 +0000807PyTclObject_str(PyTclObject *self, void *ignored)
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000808{
809 char *s;
810 int len;
811 if (self->string && PyUnicode_Check(self->string)) {
812 Py_INCREF(self->string);
813 return self->string;
814 }
815 /* XXX Could chache result if it is non-ASCII. */
816 s = Tcl_GetStringFromObj(self->value, &len);
817 return PyUnicode_DecodeUTF8(s, len, "strict");
818}
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000819
Martin v. Löwisffad6332002-11-26 09:28:05 +0000820static PyObject *
821PyTclObject_repr(PyTclObject *self)
822{
Walter Dörwald7569dfe2007-05-19 21:49:49 +0000823 return PyUnicode_FromFormat("<%s object at %p>",
824 self->value->typePtr->name, self->value);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000825}
826
Mark Dickinson211c6252009-02-01 10:28:51 +0000827#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
828
829static PyObject *
830PyTclObject_richcompare(PyObject *self, PyObject *other, int op)
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000831{
Mark Dickinson211c6252009-02-01 10:28:51 +0000832 int result;
833 PyObject *v;
834
835 /* neither argument should be NULL, unless something's gone wrong */
836 if (self == NULL || other == NULL) {
837 PyErr_BadInternalCall();
838 return NULL;
839 }
840
841 /* both arguments should be instances of PyTclObject */
842 if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) {
843 v = Py_NotImplemented;
844 goto finished;
845 }
846
847 if (self == other)
848 /* fast path when self and other are identical */
849 result = 0;
850 else
851 result = strcmp(Tcl_GetString(((PyTclObject *)self)->value),
852 Tcl_GetString(((PyTclObject *)other)->value));
853 /* Convert return value to a Boolean */
854 switch (op) {
855 case Py_EQ:
856 v = TEST_COND(result == 0);
857 break;
858 case Py_NE:
859 v = TEST_COND(result != 0);
860 break;
861 case Py_LE:
862 v = TEST_COND(result <= 0);
863 break;
864 case Py_GE:
865 v = TEST_COND(result >= 0);
866 break;
867 case Py_LT:
868 v = TEST_COND(result < 0);
869 break;
870 case Py_GT:
871 v = TEST_COND(result > 0);
872 break;
873 default:
874 PyErr_BadArgument();
875 return NULL;
876 }
877 finished:
878 Py_INCREF(v);
879 return v;
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000880}
881
Martin v. Löwis39195712003-01-04 00:33:13 +0000882PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
883
Martin v. Löwisffad6332002-11-26 09:28:05 +0000884static PyObject*
885get_typename(PyTclObject* obj, void* ignored)
886{
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000887 return PyUnicode_FromString(obj->value->typePtr->name);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000888}
889
Martin v. Löwis39195712003-01-04 00:33:13 +0000890
Martin v. Löwisffad6332002-11-26 09:28:05 +0000891static PyGetSetDef PyTclObject_getsetlist[] = {
Martin v. Löwis39195712003-01-04 00:33:13 +0000892 {"typename", (getter)get_typename, NULL, get_typename__doc__},
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000893 {"string", (getter)PyTclObject_string, NULL,
Martin v. Löwis39195712003-01-04 00:33:13 +0000894 PyTclObject_string__doc__},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000895 {0},
896};
897
Neal Norwitz227b5332006-03-22 09:28:35 +0000898static PyTypeObject PyTclObject_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000899 PyVarObject_HEAD_INIT(NULL, 0)
Martin v. Löwisffad6332002-11-26 09:28:05 +0000900 "_tkinter.Tcl_Obj", /*tp_name*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000901 sizeof(PyTclObject), /*tp_basicsize*/
902 0, /*tp_itemsize*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000903 /* methods */
Mark Dickinson211c6252009-02-01 10:28:51 +0000904 (destructor)PyTclObject_dealloc,/*tp_dealloc*/
905 0, /*tp_print*/
906 0, /*tp_getattr*/
907 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000908 0, /*tp_reserved*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000909 (reprfunc)PyTclObject_repr, /*tp_repr*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000910 0, /*tp_as_number*/
911 0, /*tp_as_sequence*/
912 0, /*tp_as_mapping*/
913 0, /*tp_hash*/
914 0, /*tp_call*/
915 (reprfunc)PyTclObject_str, /*tp_str*/
916 PyObject_GenericGetAttr, /*tp_getattro*/
917 0, /*tp_setattro*/
918 0, /*tp_as_buffer*/
919 Py_TPFLAGS_DEFAULT, /*tp_flags*/
920 0, /*tp_doc*/
921 0, /*tp_traverse*/
922 0, /*tp_clear*/
923 PyTclObject_richcompare, /*tp_richcompare*/
924 0, /*tp_weaklistoffset*/
925 0, /*tp_iter*/
926 0, /*tp_iternext*/
927 0, /*tp_methods*/
928 0, /*tp_members*/
929 PyTclObject_getsetlist, /*tp_getset*/
930 0, /*tp_base*/
931 0, /*tp_dict*/
932 0, /*tp_descr_get*/
933 0, /*tp_descr_set*/
934 0, /*tp_dictoffset*/
935 0, /*tp_init*/
936 0, /*tp_alloc*/
937 0, /*tp_new*/
938 0, /*tp_free*/
939 0, /*tp_is_gc*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000940};
941
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000942static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000943AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000944{
945 Tcl_Obj *result;
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +0000946 long longVal;
947 int overflow;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000948
Christian Heimes72b710a2008-05-26 13:28:38 +0000949 if (PyBytes_Check(value))
950 return Tcl_NewStringObj(PyBytes_AS_STRING(value),
951 PyBytes_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));
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +0000954 else if (PyLong_CheckExact(value) &&
955 ((longVal = PyLong_AsLongAndOverflow(value, &overflow)),
956 !overflow)) {
957 /* If there is an overflow in the long conversion,
958 fall through to default object handling. */
959 return Tcl_NewLongObj(longVal);
960 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000961 else if (PyFloat_Check(value))
962 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
963 else if (PyTuple_Check(value)) {
964 Tcl_Obj **argv = (Tcl_Obj**)
965 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
966 int i;
967 if(!argv)
968 return 0;
969 for(i=0;i<PyTuple_Size(value);i++)
970 argv[i] = AsObj(PyTuple_GetItem(value,i));
971 result = Tcl_NewListObj(PyTuple_Size(value), argv);
972 ckfree(FREECAST argv);
973 return result;
974 }
975 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000976 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000977 Py_ssize_t size = PyUnicode_GET_SIZE(value);
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000978 /* This #ifdef assumes that Tcl uses UCS-2.
979 See TCL_UTF_MAX test above. */
Martin v. Löwis6f29ff32003-04-16 20:34:55 +0000980#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
Christian Heimesa34706f2008-01-04 03:06:10 +0000981 Tcl_UniChar *outbuf = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000982 Py_ssize_t i;
Christian Heimesa34706f2008-01-04 03:06:10 +0000983 size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
984 if (allocsize >= size)
985 outbuf = (Tcl_UniChar*)ckalloc(allocsize);
986 /* Else overflow occurred, and we take the next exit */
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000987 if (!outbuf) {
988 PyErr_NoMemory();
989 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000990 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000991 for (i = 0; i < size; i++) {
992 if (inbuf[i] >= 0x10000) {
993 /* Tcl doesn't do UTF-16, yet. */
994 PyErr_SetString(PyExc_ValueError,
995 "unsupported character");
996 ckfree(FREECAST outbuf);
997 return NULL;
998 }
999 outbuf[i] = inbuf[i];
1000 }
1001 result = Tcl_NewUnicodeObj(outbuf, size);
1002 ckfree(FREECAST outbuf);
1003 return result;
1004#else
1005 return Tcl_NewUnicodeObj(inbuf, size);
1006#endif
1007
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001008 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001009 else if(PyTclObject_Check(value)) {
1010 Tcl_Obj *v = ((PyTclObject*)value)->value;
1011 Tcl_IncrRefCount(v);
1012 return v;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001013 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001014 else {
1015 PyObject *v = PyObject_Str(value);
1016 if (!v)
1017 return 0;
1018 result = AsObj(v);
1019 Py_DECREF(v);
1020 return result;
1021 }
1022}
1023
Martin v. Löwisffad6332002-11-26 09:28:05 +00001024static PyObject*
1025FromObj(PyObject* tkapp, Tcl_Obj *value)
1026{
1027 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001028 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +00001029
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001030 if (value->typePtr == NULL) {
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001031 return PyUnicode_FromStringAndSize(value->bytes,
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001032 value->length);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001033 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001034
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001035 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001036 result = value->internalRep.longValue ? Py_True : Py_False;
1037 Py_INCREF(result);
1038 return result;
1039 }
1040
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001041 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001042 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +00001043 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Christian Heimes72b710a2008-05-26 13:28:38 +00001044 return PyBytes_FromStringAndSize(data, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001045 }
1046
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001047 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001048 return PyFloat_FromDouble(value->internalRep.doubleValue);
1049 }
1050
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001051 if (value->typePtr == app->IntType) {
Christian Heimes217cfd12007-12-02 14:31:20 +00001052 return PyLong_FromLong(value->internalRep.longValue);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001053 }
1054
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001055 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001056 int size;
1057 int i, status;
1058 PyObject *elem;
1059 Tcl_Obj *tcl_elem;
1060
1061 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
1062 if (status == TCL_ERROR)
1063 return Tkinter_Error(tkapp);
1064 result = PyTuple_New(size);
1065 if (!result)
1066 return NULL;
1067 for (i = 0; i < size; i++) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001068 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
Martin v. Löwisffad6332002-11-26 09:28:05 +00001069 value, i, &tcl_elem);
1070 if (status == TCL_ERROR) {
1071 Py_DECREF(result);
1072 return Tkinter_Error(tkapp);
1073 }
1074 elem = FromObj(tkapp, tcl_elem);
1075 if (!elem) {
1076 Py_DECREF(result);
1077 return NULL;
1078 }
1079 PyTuple_SetItem(result, i, elem);
1080 }
1081 return result;
1082 }
1083
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001084 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001085 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +00001086 }
1087
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001088 if (value->typePtr == app->StringType) {
Martin v. Löwis6f29ff32003-04-16 20:34:55 +00001089#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
Martin v. Löwisffad6332002-11-26 09:28:05 +00001090 PyObject *result;
1091 int size;
1092 Tcl_UniChar *input;
1093 Py_UNICODE *output;
1094
1095 size = Tcl_GetCharLength(value);
1096 result = PyUnicode_FromUnicode(NULL, size);
1097 if (!result)
1098 return NULL;
1099 input = Tcl_GetUnicode(value);
1100 output = PyUnicode_AS_UNICODE(result);
1101 while (size--)
1102 *output++ = *input++;
1103 return result;
1104#else
1105 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1106 Tcl_GetCharLength(value));
1107#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +00001108 }
1109
1110 return newPyTclObject(value);
1111}
1112
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001113/* This mutex synchronizes inter-thread command calls. */
1114
1115TCL_DECLARE_MUTEX(call_mutex)
1116
1117typedef struct Tkapp_CallEvent {
1118 Tcl_Event ev; /* Must be first */
1119 TkappObject *self;
1120 PyObject *args;
1121 int flags;
1122 PyObject **res;
1123 PyObject **exc_type, **exc_value, **exc_tb;
Guilherme Polo491aee22009-02-06 23:16:11 +00001124 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001125} Tkapp_CallEvent;
1126
1127void
1128Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001129{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001130 int i;
1131 for (i = 0; i < objc; i++)
1132 Tcl_DecrRefCount(objv[i]);
1133 if (objv != objStore)
1134 ckfree(FREECAST objv);
1135}
Guido van Rossum18468821994-06-20 07:49:28 +00001136
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001137/* Convert Python objects to Tcl objects. This must happen in the
1138 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001139
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001140static Tcl_Obj**
1141Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1142{
1143 Tcl_Obj **objv = objStore;
Martin v. Löwis7d134952002-12-12 19:05:48 +00001144 int objc = 0, i;
Guido van Rossum212643f1998-04-29 16:22:14 +00001145 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +00001146 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001147
Guido van Rossum212643f1998-04-29 16:22:14 +00001148 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +00001149 objv[0] = AsObj(args);
1150 if (objv[0] == 0)
1151 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001152 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +00001153 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001154 }
1155 else {
Guido van Rossum632de272000-03-29 00:19:50 +00001156 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001157
Guido van Rossum632de272000-03-29 00:19:50 +00001158 if (objc > ARGSZ) {
1159 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1160 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001161 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +00001162 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +00001163 goto finally;
1164 }
1165 }
1166
Guido van Rossum632de272000-03-29 00:19:50 +00001167 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001168 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +00001169 if (v == Py_None) {
1170 objc = i;
1171 break;
1172 }
Guido van Rossum632de272000-03-29 00:19:50 +00001173 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +00001174 if (!objv[i]) {
1175 /* Reset objc, so it attempts to clear
1176 objects only up to i. */
1177 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +00001178 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001179 }
Guido van Rossum632de272000-03-29 00:19:50 +00001180 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001181 }
1182 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001183 *pobjc = objc;
1184 return objv;
1185finally:
1186 Tkapp_CallDeallocArgs(objv, objStore, objc);
1187 return NULL;
1188}
Guido van Rossum212643f1998-04-29 16:22:14 +00001189
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001190/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001191
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001192static PyObject*
1193Tkapp_CallResult(TkappObject *self)
1194{
1195 PyObject *res = NULL;
1196 if(self->wantobjects) {
1197 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001198 /* Not sure whether the IncrRef is necessary, but something
1199 may overwrite the interpreter result while we are
1200 converting it. */
1201 Tcl_IncrRefCount(value);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001202 res = FromObj((PyObject*)self, value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001203 Tcl_DecrRefCount(value);
1204 } else {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001205 const char *s = Tcl_GetStringResult(self->interp);
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001206 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001207
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001208 res = PyUnicode_FromStringAndSize(s, (int)(p-s));
Guido van Rossum990f5c62000-05-04 15:07:16 +00001209 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001210 return res;
1211}
Guido van Rossum632de272000-03-29 00:19:50 +00001212
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001213/* Tkapp_CallProc is the event procedure that is executed in the context of
1214 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1215 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001216
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001217static int
1218Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1219{
1220 Tcl_Obj *objStore[ARGSZ];
1221 Tcl_Obj **objv;
1222 int objc;
1223 int i;
1224 ENTER_PYTHON
1225 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1226 if (!objv) {
1227 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1228 *(e->res) = NULL;
1229 }
1230 LEAVE_PYTHON
1231 if (!objv)
1232 goto done;
1233 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1234 ENTER_PYTHON
1235 if (i == TCL_ERROR) {
1236 *(e->res) = NULL;
1237 *(e->exc_type) = NULL;
1238 *(e->exc_tb) = NULL;
1239 *(e->exc_value) = PyObject_CallFunction(
1240 Tkinter_TclError, "s",
1241 Tcl_GetStringResult(e->self->interp));
1242 }
1243 else {
1244 *(e->res) = Tkapp_CallResult(e->self);
1245 }
1246 LEAVE_PYTHON
Guilherme Polo491aee22009-02-06 23:16:11 +00001247
1248 Tkapp_CallDeallocArgs(objv, objStore, objc);
1249done:
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001250 /* Wake up calling thread. */
1251 Tcl_MutexLock(&call_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00001252 Tcl_ConditionNotify(e->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001253 Tcl_MutexUnlock(&call_mutex);
1254 return 1;
1255}
1256
1257/* This is the main entry point for calling a Tcl command.
1258 It supports three cases, with regard to threading:
1259 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1260 the context of the calling thread.
1261 2. Tcl is threaded, caller of the command is in the interpreter thread:
1262 Execute the command in the calling thread. Since the Tcl lock will
1263 not be used, we can merge that with case 1.
1264 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1265 the interpreter thread. Allocation of Tcl objects needs to occur in the
1266 interpreter thread, so we ship the PyObject* args to the target thread,
1267 and perform processing there. */
1268
1269static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001270Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001271{
1272 Tcl_Obj *objStore[ARGSZ];
1273 Tcl_Obj **objv = NULL;
1274 int objc, i;
1275 PyObject *res = NULL;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001276 TkappObject *self = (TkappObject*)selfptr;
Guilherme Polo7f423952009-02-02 21:17:09 +00001277 int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001278
Guido van Rossum992d4a32007-07-11 13:09:30 +00001279 /* If args is a single tuple, replace with contents of tuple */
1280 if (1 == PyTuple_Size(args)){
1281 PyObject* item = PyTuple_GetItem(args, 0);
1282 if (PyTuple_Check(item))
1283 args = item;
1284 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001285#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001286 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1287 /* We cannot call the command directly. Instead, we must
1288 marshal the parameters to the interpreter thread. */
1289 Tkapp_CallEvent *ev;
Guilherme Polo491aee22009-02-06 23:16:11 +00001290 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001291 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001292 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001293 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001294 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1295 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1296 ev->self = self;
1297 ev->args = args;
1298 ev->res = &res;
1299 ev->exc_type = &exc_type;
1300 ev->exc_value = &exc_value;
1301 ev->exc_tb = &exc_tb;
Guilherme Polo491aee22009-02-06 23:16:11 +00001302 ev->done = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001303
Guilherme Polo491aee22009-02-06 23:16:11 +00001304 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001305
1306 if (res == NULL) {
1307 if (exc_type)
1308 PyErr_Restore(exc_type, exc_value, exc_tb);
1309 else
1310 PyErr_SetObject(Tkinter_TclError, exc_value);
1311 }
Guilherme Polo491aee22009-02-06 23:16:11 +00001312 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001313 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001314 else
Martin v. Löwisa9656492003-03-30 08:44:58 +00001315#endif
1316 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001317
1318 objv = Tkapp_CallArgs(args, objStore, &objc);
1319 if (!objv)
1320 return NULL;
1321
1322 ENTER_TCL
1323
1324 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1325
1326 ENTER_OVERLAP
1327
1328 if (i == TCL_ERROR)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001329 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001330 else
1331 res = Tkapp_CallResult(self);
1332
1333 LEAVE_OVERLAP_TCL
1334
1335 Tkapp_CallDeallocArgs(objv, objStore, objc);
1336 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001337 return res;
1338}
1339
1340
1341static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001342Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001343{
Guido van Rossum212643f1998-04-29 16:22:14 +00001344 /* Could do the same here as for Tkapp_Call(), but this is not used
1345 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1346 way for the user to do what all its Global* variants do (save and
1347 reset the scope pointer, call the local version, restore the saved
1348 scope pointer). */
1349
Guido van Rossum62320c91998-06-15 04:36:09 +00001350 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001351 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001352
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001353 CHECK_TCL_APPARTMENT;
1354
Guido van Rossum62320c91998-06-15 04:36:09 +00001355 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001356 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001357 int err;
1358 ENTER_TCL
1359 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001360 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001361 if (err == TCL_ERROR)
1362 res = Tkinter_Error(self);
1363 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001364 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001365 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001366 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001367 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001368
1369 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001370}
1371
1372static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001373Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001374{
Barry Warsawfa701a81997-01-16 00:15:11 +00001375 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001376 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001377 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001378
Guido van Rossum43713e52000-02-29 13:59:29 +00001379 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001380 return NULL;
1381
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001382 CHECK_TCL_APPARTMENT;
1383
Guido van Rossum00d93061998-05-28 23:06:38 +00001384 ENTER_TCL
1385 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001386 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001387 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001388 res = Tkinter_Error(self);
1389 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001390 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001391 LEAVE_OVERLAP_TCL
1392 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001393}
1394
1395static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001396Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001397{
Barry Warsawfa701a81997-01-16 00:15:11 +00001398 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001399 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001400 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001401
Guido van Rossum43713e52000-02-29 13:59:29 +00001402 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001403 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001404
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001405 CHECK_TCL_APPARTMENT;
1406
Guido van Rossum00d93061998-05-28 23:06:38 +00001407 ENTER_TCL
1408 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001409 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001410 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001411 res = Tkinter_Error(self);
1412 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001413 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001414 LEAVE_OVERLAP_TCL
1415 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001416}
1417
1418static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001419Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001420{
Barry Warsawfa701a81997-01-16 00:15:11 +00001421 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001422 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001423 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001424
Guido van Rossum43713e52000-02-29 13:59:29 +00001425 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001426 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001427
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001428 CHECK_TCL_APPARTMENT;
1429
Guido van Rossum00d93061998-05-28 23:06:38 +00001430 ENTER_TCL
1431 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001432 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001433 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001434 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001435
Guido van Rossum62320c91998-06-15 04:36:09 +00001436 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001437 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001438 LEAVE_OVERLAP_TCL
1439 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001440}
1441
1442static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001443Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001444{
Barry Warsawfa701a81997-01-16 00:15:11 +00001445 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001446 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001447 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001448
Guido van Rossum35d43371997-08-02 00:09:09 +00001449 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001450 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001451
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001452 CHECK_TCL_APPARTMENT;
1453
Guido van Rossum00d93061998-05-28 23:06:38 +00001454 ENTER_TCL
1455 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001456 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001457 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001458 res = Tkinter_Error(self);
1459 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001460 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001461 LEAVE_OVERLAP_TCL
1462 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001463}
1464
1465static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001466Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001467{
Barry Warsawfa701a81997-01-16 00:15:11 +00001468 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001469
Guido van Rossum43713e52000-02-29 13:59:29 +00001470 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001471 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001472 CHECK_TCL_APPARTMENT;
1473
Guido van Rossum00d93061998-05-28 23:06:38 +00001474 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001475 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001476 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001477
Barry Warsawfa701a81997-01-16 00:15:11 +00001478 Py_INCREF(Py_None);
1479 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001480}
1481
Barry Warsawfa701a81997-01-16 00:15:11 +00001482
1483
Guido van Rossum18468821994-06-20 07:49:28 +00001484/** Tcl Variable **/
1485
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001486TCL_DECLARE_MUTEX(var_mutex)
1487
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001488typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001489typedef struct VarEvent {
1490 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001491 PyObject *self;
1492 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001493 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001494 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001495 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001496 PyObject **exc_type;
1497 PyObject **exc_val;
Guilherme Polo491aee22009-02-06 23:16:11 +00001498 Tcl_Condition *cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001499} VarEvent;
1500
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001501static int
1502varname_converter(PyObject *in, void *_out)
1503{
1504 char **out = (char**)_out;
Christian Heimes72b710a2008-05-26 13:28:38 +00001505 if (PyBytes_Check(in)) {
1506 *out = PyBytes_AsString(in);
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001507 return 1;
1508 }
Guido van Rossumf761e102007-07-23 18:34:37 +00001509 if (PyUnicode_Check(in)) {
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00001510 *out = _PyUnicode_AsString(in);
Guido van Rossumf761e102007-07-23 18:34:37 +00001511 return 1;
1512 }
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001513 if (PyTclObject_Check(in)) {
1514 *out = PyTclObject_TclString(in);
1515 return 1;
1516 }
1517 /* XXX: Should give diagnostics. */
1518 return 0;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001519}
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001520
Martin v. Löwis59683e82008-06-13 07:50:45 +00001521static void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001522var_perform(VarEvent *ev)
1523{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001524 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1525 if (!*(ev->res)) {
1526 PyObject *exc, *val, *tb;
1527 PyErr_Fetch(&exc, &val, &tb);
1528 PyErr_NormalizeException(&exc, &val, &tb);
1529 *(ev->exc_type) = exc;
1530 *(ev->exc_val) = val;
1531 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001532 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001533
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001534}
1535
1536static int
1537var_proc(VarEvent* ev, int flags)
1538{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001539 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001540 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001541 Tcl_MutexLock(&var_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00001542 Tcl_ConditionNotify(ev->cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001543 Tcl_MutexUnlock(&var_mutex);
1544 LEAVE_PYTHON
1545 return 1;
1546}
1547
1548static PyObject*
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001549var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001550{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001551 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisa9656492003-03-30 08:44:58 +00001552#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001553 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001554 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001555 VarEvent *ev;
1556 PyObject *res, *exc_type, *exc_val;
Guilherme Polo491aee22009-02-06 23:16:11 +00001557 Tcl_Condition cond = NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001558
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001559 /* The current thread is not the interpreter thread. Marshal
1560 the call to the interpreter thread, then wait for
1561 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001562 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001563 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001564
1565 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1566
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001567 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001568 ev->args = args;
1569 ev->flags = flags;
1570 ev->func = func;
1571 ev->res = &res;
1572 ev->exc_type = &exc_type;
1573 ev->exc_val = &exc_val;
Guilherme Polo491aee22009-02-06 23:16:11 +00001574 ev->cond = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001575 ev->ev.proc = (Tcl_EventProc*)var_proc;
Guilherme Polo491aee22009-02-06 23:16:11 +00001576 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
1577 Tcl_ConditionFinalize(&cond);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001578 if (!res) {
1579 PyErr_SetObject(exc_type, exc_val);
1580 Py_DECREF(exc_type);
1581 Py_DECREF(exc_val);
1582 return NULL;
1583 }
1584 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001585 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001586#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001587 /* Tcl is not threaded, or this is the interpreter thread. */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001588 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001589}
1590
Guido van Rossum18468821994-06-20 07:49:28 +00001591static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001592SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001593{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001594 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001595 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001596 PyObject *res = NULL;
1597 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001598
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001599 if (PyArg_ParseTuple(args, "O&O:setvar",
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001600 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001601 /* XXX Acquire tcl lock??? */
1602 newval = AsObj(newValue);
1603 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001604 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001605 ENTER_TCL
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001606 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001607 newval, flags);
1608 ENTER_OVERLAP
1609 if (!ok)
1610 Tkinter_Error(self);
1611 else {
1612 res = Py_None;
1613 Py_INCREF(res);
1614 }
1615 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001616 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001617 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001618 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001619 if (PyArg_ParseTuple(args, "ssO:setvar",
1620 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001621 /* XXX must hold tcl lock already??? */
1622 newval = AsObj(newValue);
1623 ENTER_TCL
1624 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1625 ENTER_OVERLAP
1626 if (!ok)
1627 Tkinter_Error(self);
1628 else {
1629 res = Py_None;
1630 Py_INCREF(res);
1631 }
1632 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001633 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001634 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001635 return NULL;
1636 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001637 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001638 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001639}
1640
1641static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001642Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001643{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001644 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001645}
1646
1647static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001648Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001649{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001650 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001651}
1652
Barry Warsawfa701a81997-01-16 00:15:11 +00001653
1654
Guido van Rossum18468821994-06-20 07:49:28 +00001655static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001656GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001657{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001658 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001659 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001660 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001661
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001662 if (!PyArg_ParseTuple(args, "O&|s:getvar",
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001663 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001664 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001665
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001666 ENTER_TCL
1667 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1668 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001669 if (tres == NULL) {
1670 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1671 } else {
1672 if (((TkappObject*)self)->wantobjects) {
1673 res = FromObj(self, tres);
1674 }
1675 else {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001676 res = PyUnicode_FromString(Tcl_GetString(tres));
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001677 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001678 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001679 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001680 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001681}
1682
1683static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001684Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001685{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001686 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001687}
1688
1689static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001690Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001691{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001692 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001693}
1694
Barry Warsawfa701a81997-01-16 00:15:11 +00001695
1696
Guido van Rossum18468821994-06-20 07:49:28 +00001697static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001698UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001699{
Guido van Rossum35d43371997-08-02 00:09:09 +00001700 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001701 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001702 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001703
Guido van Rossum43713e52000-02-29 13:59:29 +00001704 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001705 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001706
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001707 ENTER_TCL
1708 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1709 ENTER_OVERLAP
1710 if (code == TCL_ERROR)
1711 res = Tkinter_Error(self);
1712 else {
1713 Py_INCREF(Py_None);
1714 res = Py_None;
1715 }
1716 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001717 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001718}
1719
1720static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001721Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001722{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001723 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001724}
1725
1726static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001727Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001728{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001729 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001730}
1731
Barry Warsawfa701a81997-01-16 00:15:11 +00001732
1733
Guido van Rossum18468821994-06-20 07:49:28 +00001734/** Tcl to Python **/
1735
1736static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001737Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001738{
Barry Warsawfa701a81997-01-16 00:15:11 +00001739 char *s;
1740 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001741
Martin v. Löwisffad6332002-11-26 09:28:05 +00001742 if (PyTuple_Size(args) == 1) {
1743 PyObject* o = PyTuple_GetItem(args, 0);
Christian Heimes217cfd12007-12-02 14:31:20 +00001744 if (PyLong_Check(o)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001745 Py_INCREF(o);
1746 return o;
1747 }
1748 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001749 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001750 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001751 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001752 return Tkinter_Error(self);
1753 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001754}
1755
1756static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001757Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001758{
Barry Warsawfa701a81997-01-16 00:15:11 +00001759 char *s;
1760 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001761
Martin v. Löwisffad6332002-11-26 09:28:05 +00001762 if (PyTuple_Size(args) == 1) {
1763 PyObject *o = PyTuple_GetItem(args, 0);
1764 if (PyFloat_Check(o)) {
1765 Py_INCREF(o);
1766 return o;
1767 }
1768 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001769 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001770 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001771 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001772 return Tkinter_Error(self);
1773 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001774}
1775
1776static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001777Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001778{
Barry Warsawfa701a81997-01-16 00:15:11 +00001779 char *s;
1780 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001781
Martin v. Löwisffad6332002-11-26 09:28:05 +00001782 if (PyTuple_Size(args) == 1) {
1783 PyObject *o = PyTuple_GetItem(args, 0);
Christian Heimes217cfd12007-12-02 14:31:20 +00001784 if (PyLong_Check(o)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001785 Py_INCREF(o);
1786 return o;
1787 }
1788 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001789 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001790 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001791 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1792 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001793 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001794}
1795
1796static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001797Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001798{
Barry Warsawfa701a81997-01-16 00:15:11 +00001799 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001800 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001801 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001802
Guido van Rossum43713e52000-02-29 13:59:29 +00001803 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001804 return NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001805
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001806 CHECK_TCL_APPARTMENT;
1807
Guido van Rossum00d93061998-05-28 23:06:38 +00001808 ENTER_TCL
1809 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001810 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001811 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001812 res = Tkinter_Error(self);
1813 else
1814 res = Py_BuildValue("s", Tkapp_Result(self));
1815 LEAVE_OVERLAP_TCL
1816 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001817}
1818
1819static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001820Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001821{
Barry Warsawfa701a81997-01-16 00:15:11 +00001822 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001823 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001824 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001825 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001826
Guido van Rossum43713e52000-02-29 13:59:29 +00001827 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001828 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001829
1830 CHECK_TCL_APPARTMENT;
1831
Guido van Rossum00d93061998-05-28 23:06:38 +00001832 ENTER_TCL
1833 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001834 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001835 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001836 res = Tkinter_Error(self);
1837 else
1838 res = Py_BuildValue("l", v);
1839 LEAVE_OVERLAP_TCL
1840 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001841}
1842
1843static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001844Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001845{
Barry Warsawfa701a81997-01-16 00:15:11 +00001846 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001847 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001848 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001849 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001850
Guido van Rossum43713e52000-02-29 13:59:29 +00001851 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001852 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001853 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001854 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001855 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001856 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001857 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001858 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001859 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001860 res = Tkinter_Error(self);
1861 else
1862 res = Py_BuildValue("d", v);
1863 LEAVE_OVERLAP_TCL
1864 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001865}
1866
1867static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001868Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001869{
Barry Warsawfa701a81997-01-16 00:15:11 +00001870 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001871 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001872 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001873 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001874
Guido van Rossum43713e52000-02-29 13:59:29 +00001875 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001876 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001877 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001878 ENTER_TCL
1879 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001880 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001881 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001882 res = Tkinter_Error(self);
1883 else
1884 res = Py_BuildValue("i", v);
1885 LEAVE_OVERLAP_TCL
1886 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001887}
1888
Barry Warsawfa701a81997-01-16 00:15:11 +00001889
1890
Guido van Rossum18468821994-06-20 07:49:28 +00001891static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001892Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001893{
Barry Warsawfa701a81997-01-16 00:15:11 +00001894 char *list;
1895 int argc;
1896 char **argv;
1897 PyObject *v;
1898 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001899
Martin v. Löwisffad6332002-11-26 09:28:05 +00001900 if (PyTuple_Size(args) == 1) {
1901 v = PyTuple_GetItem(args, 0);
1902 if (PyTuple_Check(v)) {
1903 Py_INCREF(v);
1904 return v;
1905 }
1906 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001907 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001908 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001909
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001910 if (Tcl_SplitList(Tkapp_Interp(self), list,
Neal Norwitzd1c55102003-05-29 00:17:03 +00001911 &argc, &argv) == TCL_ERROR) {
1912 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001913 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001914 }
Guido van Rossum18468821994-06-20 07:49:28 +00001915
Barry Warsawfa701a81997-01-16 00:15:11 +00001916 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001917 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001918
Barry Warsawfa701a81997-01-16 00:15:11 +00001919 for (i = 0; i < argc; i++) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001920 PyObject *s = PyUnicode_FromString(argv[i]);
Barry Warsawfa701a81997-01-16 00:15:11 +00001921 if (!s || PyTuple_SetItem(v, i, s)) {
1922 Py_DECREF(v);
1923 v = NULL;
1924 goto finally;
1925 }
1926 }
Guido van Rossum18468821994-06-20 07:49:28 +00001927
Barry Warsawfa701a81997-01-16 00:15:11 +00001928 finally:
1929 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001930 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001931 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001932}
1933
1934static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001935Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001936{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001937 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001938 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001939
Martin v. Löwisffad6332002-11-26 09:28:05 +00001940 if (PyTuple_Size(args) == 1) {
1941 PyObject* o = PyTuple_GetItem(args, 0);
1942 if (PyTuple_Check(o)) {
1943 o = SplitObj(o);
1944 return o;
1945 }
1946 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001947 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001948 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00001949 v = Split(list);
1950 PyMem_Free(list);
1951 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001952}
1953
1954static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001955Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001956{
Barry Warsawfa701a81997-01-16 00:15:11 +00001957 char *s = Merge(args);
1958 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001959
Barry Warsawfa701a81997-01-16 00:15:11 +00001960 if (s) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001961 res = PyUnicode_FromString(s);
Barry Warsawfa701a81997-01-16 00:15:11 +00001962 ckfree(s);
1963 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001964
1965 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001966}
1967
Barry Warsawfa701a81997-01-16 00:15:11 +00001968
1969
Guido van Rossum18468821994-06-20 07:49:28 +00001970/** Tcl Command **/
1971
Guido van Rossum00d93061998-05-28 23:06:38 +00001972/* Client data struct */
1973typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001974 PyObject *self;
1975 PyObject *func;
1976} PythonCmd_ClientData;
1977
1978static int
Fred Drake509d79a2000-07-08 04:04:38 +00001979PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001980{
1981 errorInCmd = 1;
1982 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1983 LEAVE_PYTHON
1984 return TCL_ERROR;
1985}
1986
Guido van Rossum18468821994-06-20 07:49:28 +00001987/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001988 * function or method.
1989 */
Guido van Rossum18468821994-06-20 07:49:28 +00001990static int
Fred Drake509d79a2000-07-08 04:04:38 +00001991PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001992{
Guido van Rossum00d93061998-05-28 23:06:38 +00001993 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Hirokazu Yamamotode603472008-11-18 04:33:04 +00001994 PyObject *self, *func, *arg, *res;
Guido van Rossum2834b972000-10-06 16:58:26 +00001995 int i, rv;
Christian Heimes57dddfb2008-01-02 18:30:52 +00001996 Tcl_Obj *obj_res;
Guido van Rossum18468821994-06-20 07:49:28 +00001997
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001998 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001999
Barry Warsawfa701a81997-01-16 00:15:11 +00002000 /* TBD: no error checking here since we know, via the
2001 * Tkapp_CreateCommand() that the client data is a two-tuple
2002 */
Guido van Rossum00d93061998-05-28 23:06:38 +00002003 self = data->self;
2004 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00002005
Barry Warsawfa701a81997-01-16 00:15:11 +00002006 /* Create argument list (argv1, ..., argvN) */
2007 if (!(arg = PyTuple_New(argc - 1)))
2008 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00002009
Barry Warsawfa701a81997-01-16 00:15:11 +00002010 for (i = 0; i < (argc - 1); i++) {
Hirokazu Yamamotode603472008-11-18 04:33:04 +00002011 PyObject *s = PyUnicode_FromString(argv[i + 1]);
Barry Warsawfa701a81997-01-16 00:15:11 +00002012 if (!s || PyTuple_SetItem(arg, i, s)) {
2013 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00002014 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00002015 }
2016 }
2017 res = PyEval_CallObject(func, arg);
2018 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00002019
Barry Warsawfa701a81997-01-16 00:15:11 +00002020 if (res == NULL)
2021 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00002022
Christian Heimes57dddfb2008-01-02 18:30:52 +00002023 obj_res = AsObj(res);
2024 if (obj_res == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002025 Py_DECREF(res);
2026 return PythonCmd_Error(interp);
2027 }
Guido van Rossum2834b972000-10-06 16:58:26 +00002028 else {
Christian Heimes57dddfb2008-01-02 18:30:52 +00002029 Tcl_SetObjResult(Tkapp_Interp(self), obj_res);
Guido van Rossum2834b972000-10-06 16:58:26 +00002030 rv = TCL_OK;
2031 }
2032
Barry Warsawfa701a81997-01-16 00:15:11 +00002033 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00002034
Guido van Rossum00d93061998-05-28 23:06:38 +00002035 LEAVE_PYTHON
2036
Guido van Rossum2834b972000-10-06 16:58:26 +00002037 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002038}
2039
2040static void
Fred Drake509d79a2000-07-08 04:04:38 +00002041PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002042{
Guido van Rossum00d93061998-05-28 23:06:38 +00002043 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2044
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002045 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002046 Py_XDECREF(data->self);
2047 Py_XDECREF(data->func);
2048 PyMem_DEL(data);
2049 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002050}
2051
Barry Warsawfa701a81997-01-16 00:15:11 +00002052
2053
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002054
2055TCL_DECLARE_MUTEX(command_mutex)
2056
2057typedef struct CommandEvent{
2058 Tcl_Event ev;
2059 Tcl_Interp* interp;
2060 char *name;
2061 int create;
2062 int *status;
2063 ClientData *data;
Guilherme Polo491aee22009-02-06 23:16:11 +00002064 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002065} CommandEvent;
2066
2067static int
2068Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002069{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002070 if (ev->create)
2071 *ev->status = Tcl_CreateCommand(
2072 ev->interp, ev->name, PythonCmd,
2073 ev->data, PythonCmdDelete) == NULL;
2074 else
2075 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2076 Tcl_MutexLock(&command_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00002077 Tcl_ConditionNotify(ev->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002078 Tcl_MutexUnlock(&command_mutex);
2079 return 1;
2080}
2081
2082static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002083Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002084{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002085 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002086 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002087 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002088 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002089 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002090
Guido van Rossum43713e52000-02-29 13:59:29 +00002091 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002092 return NULL;
2093 if (!PyCallable_Check(func)) {
2094 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002095 return NULL;
2096 }
Guido van Rossum18468821994-06-20 07:49:28 +00002097
Martin v. Löwisa9656492003-03-30 08:44:58 +00002098#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002099 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002100 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002101 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002102#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002103
Guido van Rossum00d93061998-05-28 23:06:38 +00002104 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002105 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002106 return PyErr_NoMemory();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002107 Py_INCREF(self);
2108 Py_INCREF(func);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002109 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002110 data->func = func;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002111
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002112 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo491aee22009-02-06 23:16:11 +00002113 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002114 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2115 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2116 ev->interp = self->interp;
2117 ev->create = 1;
2118 ev->name = cmdName;
2119 ev->data = (ClientData)data;
2120 ev->status = &err;
Guilherme Polo491aee22009-02-06 23:16:11 +00002121 ev->done = &cond;
2122 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
2123 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002124 }
2125 else {
2126 ENTER_TCL
2127 err = Tcl_CreateCommand(
2128 Tkapp_Interp(self), cmdName, PythonCmd,
2129 (ClientData)data, PythonCmdDelete) == NULL;
2130 LEAVE_TCL
2131 }
2132 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002133 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002134 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002135 return NULL;
2136 }
Guido van Rossum18468821994-06-20 07:49:28 +00002137
Barry Warsawfa701a81997-01-16 00:15:11 +00002138 Py_INCREF(Py_None);
2139 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002140}
2141
Barry Warsawfa701a81997-01-16 00:15:11 +00002142
2143
Guido van Rossum18468821994-06-20 07:49:28 +00002144static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002145Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002146{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002147 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002148 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002149 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002150
Guido van Rossum43713e52000-02-29 13:59:29 +00002151 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002152 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002153 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo491aee22009-02-06 23:16:11 +00002154 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002155 CommandEvent *ev;
2156 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2157 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2158 ev->interp = self->interp;
2159 ev->create = 0;
2160 ev->name = cmdName;
2161 ev->status = &err;
Guilherme Polo491aee22009-02-06 23:16:11 +00002162 ev->done = &cond;
2163 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002164 &command_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00002165 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002166 }
2167 else {
2168 ENTER_TCL
2169 err = Tcl_DeleteCommand(self->interp, cmdName);
2170 LEAVE_TCL
2171 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002172 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002173 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2174 return NULL;
2175 }
2176 Py_INCREF(Py_None);
2177 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002178}
2179
Barry Warsawfa701a81997-01-16 00:15:11 +00002180
2181
Guido van Rossum00d93061998-05-28 23:06:38 +00002182#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002183/** File Handler **/
2184
Guido van Rossum00d93061998-05-28 23:06:38 +00002185typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002186 PyObject *func;
2187 PyObject *file;
2188 int id;
2189 struct _fhcdata *next;
2190} FileHandler_ClientData;
2191
2192static FileHandler_ClientData *HeadFHCD;
2193
2194static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002195NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002196{
2197 FileHandler_ClientData *p;
2198 p = PyMem_NEW(FileHandler_ClientData, 1);
2199 if (p != NULL) {
2200 Py_XINCREF(func);
2201 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002202 p->func = func;
2203 p->file = file;
2204 p->id = id;
2205 p->next = HeadFHCD;
2206 HeadFHCD = p;
2207 }
2208 return p;
2209}
2210
2211static void
Fred Drake509d79a2000-07-08 04:04:38 +00002212DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002213{
2214 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002215
2216 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002217 while ((p = *pp) != NULL) {
2218 if (p->id == id) {
2219 *pp = p->next;
2220 Py_XDECREF(p->func);
2221 Py_XDECREF(p->file);
2222 PyMem_DEL(p);
2223 }
2224 else
2225 pp = &p->next;
2226 }
2227}
2228
Guido van Rossuma597dde1995-01-10 20:56:29 +00002229static void
Fred Drake509d79a2000-07-08 04:04:38 +00002230FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002231{
Guido van Rossum00d93061998-05-28 23:06:38 +00002232 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002233 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002234
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002235 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002236 func = data->func;
2237 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002238
Barry Warsawfa701a81997-01-16 00:15:11 +00002239 arg = Py_BuildValue("(Oi)", file, (long) mask);
2240 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002241 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002242
2243 if (res == NULL) {
2244 errorInCmd = 1;
2245 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2246 }
2247 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002248 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002249}
2250
Guido van Rossum18468821994-06-20 07:49:28 +00002251static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002252Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2253 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002254{
Guido van Rossum00d93061998-05-28 23:06:38 +00002255 FileHandler_ClientData *data;
2256 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002257 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002258
Guido van Rossum2834b972000-10-06 16:58:26 +00002259 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2260 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002261 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002262
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002263 CHECK_TCL_APPARTMENT;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002264
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002265 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002266 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002267 return NULL;
2268 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002269 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002270 return NULL;
2271 }
2272
Guido van Rossuma80649b2000-03-28 20:07:05 +00002273 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002274 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002275 return NULL;
2276
Barry Warsawfa701a81997-01-16 00:15:11 +00002277 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002278 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002279 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002280 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002281 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002282 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002283}
2284
2285static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002286Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002287{
Barry Warsawfa701a81997-01-16 00:15:11 +00002288 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002289 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002290
Guido van Rossum43713e52000-02-29 13:59:29 +00002291 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002292 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002293
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002294 CHECK_TCL_APPARTMENT;
Neal Norwitz12e22172003-03-03 21:16:39 +00002295
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002296 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002297 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002298 return NULL;
2299
Guido van Rossuma80649b2000-03-28 20:07:05 +00002300 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002301
Barry Warsawfa701a81997-01-16 00:15:11 +00002302 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002303 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002304 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002305 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002306 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002307 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002308}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002309#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002310
Barry Warsawfa701a81997-01-16 00:15:11 +00002311
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002312/**** Tktt Object (timer token) ****/
2313
Jeremy Hylton938ace62002-07-17 16:30:39 +00002314static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002315
Guido van Rossum00d93061998-05-28 23:06:38 +00002316typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002317 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002318 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002319 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002320} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002321
2322static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002323Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002324{
Barry Warsawfa701a81997-01-16 00:15:11 +00002325 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002326 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002327
Guido van Rossum43713e52000-02-29 13:59:29 +00002328 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002329 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002330 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002331 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002332 v->token = NULL;
2333 }
2334 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002335 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002336 Py_DECREF(func);
2337 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002338 }
2339 Py_INCREF(Py_None);
2340 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002341}
2342
2343static PyMethodDef Tktt_methods[] =
2344{
Neal Norwitzb0493252002-03-31 14:44:22 +00002345 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002346 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002347};
2348
2349static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002350Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002351{
Barry Warsawfa701a81997-01-16 00:15:11 +00002352 TkttObject *v;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002353
Guido van Rossumb18618d2000-05-03 23:44:39 +00002354 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002355 if (v == NULL)
2356 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002357
Guido van Rossum00d93061998-05-28 23:06:38 +00002358 Py_INCREF(func);
2359 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002360 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002361
2362 /* Extra reference, deleted when called or when handler is deleted */
2363 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002364 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002365}
2366
2367static void
Fred Drake509d79a2000-07-08 04:04:38 +00002368Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002369{
Guido van Rossum00d93061998-05-28 23:06:38 +00002370 TkttObject *v = (TkttObject *)self;
2371 PyObject *func = v->func;
2372
2373 Py_XDECREF(func);
2374
Guido van Rossumb18618d2000-05-03 23:44:39 +00002375 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002376}
2377
Guido van Rossum597ac201998-05-12 14:36:19 +00002378static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002379Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002380{
Barry Warsawfa701a81997-01-16 00:15:11 +00002381 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002382 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002383
Tim Peters885d4572001-11-28 20:27:42 +00002384 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002385 v->func == NULL ? ", handler deleted" : "");
Walter Dörwald1ab83302007-05-18 17:15:44 +00002386 return PyUnicode_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002387}
2388
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002389static PyTypeObject Tktt_Type =
2390{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002391 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002392 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002393 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002394 0, /*tp_itemsize */
2395 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002396 0, /*tp_print */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002397 0, /*tp_getattr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002398 0, /*tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002399 0, /*tp_reserved */
Guido van Rossum597ac201998-05-12 14:36:19 +00002400 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002401 0, /*tp_as_number */
2402 0, /*tp_as_sequence */
2403 0, /*tp_as_mapping */
2404 0, /*tp_hash */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002405 0, /*tp_call*/
2406 0, /*tp_str*/
2407 0, /*tp_getattro*/
2408 0, /*tp_setattro*/
2409 0, /*tp_as_buffer*/
2410 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2411 0, /*tp_doc*/
2412 0, /*tp_traverse*/
2413 0, /*tp_clear*/
2414 0, /*tp_richcompare*/
2415 0, /*tp_weaklistoffset*/
2416 0, /*tp_iter*/
2417 0, /*tp_iternext*/
2418 Tktt_methods, /*tp_methods*/
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002419};
2420
Barry Warsawfa701a81997-01-16 00:15:11 +00002421
2422
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002423/** Timer Handler **/
2424
2425static void
Fred Drake509d79a2000-07-08 04:04:38 +00002426TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002427{
Guido van Rossum00d93061998-05-28 23:06:38 +00002428 TkttObject *v = (TkttObject *)clientData;
2429 PyObject *func = v->func;
2430 PyObject *res;
2431
2432 if (func == NULL)
2433 return;
2434
2435 v->func = NULL;
2436
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002437 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002438
2439 res = PyEval_CallObject(func, NULL);
2440 Py_DECREF(func);
2441 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002442
Barry Warsawfa701a81997-01-16 00:15:11 +00002443 if (res == NULL) {
2444 errorInCmd = 1;
2445 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2446 }
2447 else
2448 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002449
2450 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002451}
2452
2453static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002454Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002455{
Barry Warsawfa701a81997-01-16 00:15:11 +00002456 int milliseconds;
2457 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002458 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002459
Guido van Rossum2834b972000-10-06 16:58:26 +00002460 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2461 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002462 return NULL;
2463 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002464 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002465 return NULL;
2466 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002467
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002468 CHECK_TCL_APPARTMENT;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002469
Guido van Rossum00d93061998-05-28 23:06:38 +00002470 v = Tktt_New(func);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002471 if (v) {
2472 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2473 (ClientData)v);
2474 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002475
Guido van Rossum00d93061998-05-28 23:06:38 +00002476 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002477}
2478
Barry Warsawfa701a81997-01-16 00:15:11 +00002479
Guido van Rossum18468821994-06-20 07:49:28 +00002480/** Event Loop **/
2481
Guido van Rossum18468821994-06-20 07:49:28 +00002482static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002483Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002484{
Barry Warsawfa701a81997-01-16 00:15:11 +00002485 int threshold = 0;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002486 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002487#ifdef WITH_THREAD
2488 PyThreadState *tstate = PyThreadState_Get();
2489#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002490
Guido van Rossum43713e52000-02-29 13:59:29 +00002491 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002492 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002493
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002494 CHECK_TCL_APPARTMENT;
2495 self->dispatching = 1;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002496
Barry Warsawfa701a81997-01-16 00:15:11 +00002497 quitMainLoop = 0;
2498 while (Tk_GetNumMainWindows() > threshold &&
2499 !quitMainLoop &&
2500 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002501 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002502 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002503
2504#ifdef WITH_THREAD
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002505 if (self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002506 /* Allow other Python threads to run. */
2507 ENTER_TCL
2508 result = Tcl_DoOneEvent(0);
2509 LEAVE_TCL
2510 }
2511 else {
2512 Py_BEGIN_ALLOW_THREADS
2513 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2514 tcl_tstate = tstate;
2515 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2516 tcl_tstate = NULL;
2517 if(tcl_lock)PyThread_release_lock(tcl_lock);
2518 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002519 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002520 Py_END_ALLOW_THREADS
2521 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002522#else
2523 result = Tcl_DoOneEvent(0);
2524#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002525
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002526 if (PyErr_CheckSignals() != 0) {
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002527 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002528 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002529 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002530 if (result < 0)
2531 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002532 }
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002533 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002534 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002535
Barry Warsawfa701a81997-01-16 00:15:11 +00002536 if (errorInCmd) {
2537 errorInCmd = 0;
2538 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2539 excInCmd = valInCmd = trbInCmd = NULL;
2540 return NULL;
2541 }
2542 Py_INCREF(Py_None);
2543 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002544}
2545
2546static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002547Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002548{
Guido van Rossum35d43371997-08-02 00:09:09 +00002549 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002550 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002551
Guido van Rossum43713e52000-02-29 13:59:29 +00002552 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002553 return NULL;
2554
Guido van Rossum00d93061998-05-28 23:06:38 +00002555 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002556 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002557 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002558 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002559}
2560
2561static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002562Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002563{
2564
Guido van Rossum43713e52000-02-29 13:59:29 +00002565 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002566 return NULL;
2567
2568 quitMainLoop = 1;
2569 Py_INCREF(Py_None);
2570 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002571}
2572
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002573static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002574Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002575{
2576
Guido van Rossum43713e52000-02-29 13:59:29 +00002577 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002578 return NULL;
2579
Christian Heimes217cfd12007-12-02 14:31:20 +00002580 return PyLong_FromLong((long)Tkapp_Interp(self));
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002581}
2582
David Aschere2b4b322004-02-18 05:59:53 +00002583static PyObject *
2584Tkapp_TkInit(PyObject *self, PyObject *args)
2585{
2586 Tcl_Interp *interp = Tkapp_Interp(self);
David Aschere2b4b322004-02-18 05:59:53 +00002587 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002588 int err;
David Aschere2b4b322004-02-18 05:59:53 +00002589
Guilherme Polob681df42009-02-09 22:33:59 +00002590#ifdef TKINTER_PROTECT_LOADTK
2591 /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the
2592 * first call failed.
2593 * To avoid the deadlock, we just refuse the second call through
2594 * a static variable.
2595 */
2596 if (tk_load_failed) {
2597 PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002598 return NULL;
2599 }
Guilherme Polob681df42009-02-09 22:33:59 +00002600#endif
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002601
David Aschere2b4b322004-02-18 05:59:53 +00002602 /* We want to guard against calling Tk_Init() multiple times */
2603 CHECK_TCL_APPARTMENT;
2604 ENTER_TCL
2605 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2606 ENTER_OVERLAP
2607 if (err == TCL_ERROR) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002608 /* This sets an exception, but we cannot return right
2609 away because we need to exit the overlap first. */
2610 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002611 } else {
2612 _tk_exists = Tkapp_Result(self);
2613 }
2614 LEAVE_OVERLAP_TCL
2615 if (err == TCL_ERROR) {
2616 return NULL;
2617 }
2618 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2619 if (Tk_Init(interp) == TCL_ERROR) {
Guilherme Polob681df42009-02-09 22:33:59 +00002620 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
2621#ifdef TKINTER_PROTECT_LOADTK
2622 tk_load_failed = 1;
2623#endif
David Aschere2b4b322004-02-18 05:59:53 +00002624 return NULL;
2625 }
2626 }
2627 Py_INCREF(Py_None);
2628 return Py_None;
2629}
Barry Warsawfa701a81997-01-16 00:15:11 +00002630
Martin v. Löwisffad6332002-11-26 09:28:05 +00002631static PyObject *
2632Tkapp_WantObjects(PyObject *self, PyObject *args)
2633{
2634
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002635 int wantobjects = -1;
2636 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002637 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002638 if (wantobjects == -1)
2639 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002640 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002641
2642 Py_INCREF(Py_None);
2643 return Py_None;
2644}
2645
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002646static PyObject *
2647Tkapp_WillDispatch(PyObject *self, PyObject *args)
2648{
2649
2650 ((TkappObject*)self)->dispatching = 1;
2651
2652 Py_INCREF(Py_None);
2653 return Py_None;
2654}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002655
Barry Warsawfa701a81997-01-16 00:15:11 +00002656
Guido van Rossum18468821994-06-20 07:49:28 +00002657/**** Tkapp Method List ****/
2658
2659static PyMethodDef Tkapp_methods[] =
2660{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002661 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002662 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002663 {"call", Tkapp_Call, METH_VARARGS},
2664 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002665 {"eval", Tkapp_Eval, METH_VARARGS},
2666 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2667 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2668 {"record", Tkapp_Record, METH_VARARGS},
2669 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2670 {"setvar", Tkapp_SetVar, METH_VARARGS},
2671 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2672 {"getvar", Tkapp_GetVar, METH_VARARGS},
2673 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2674 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2675 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2676 {"getint", Tkapp_GetInt, METH_VARARGS},
2677 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2678 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2679 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2680 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2681 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2682 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2683 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2684 {"split", Tkapp_Split, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002685 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002686 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2687 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002688#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002689 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2690 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002691#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002692 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2693 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2694 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2695 {"quit", Tkapp_Quit, METH_VARARGS},
2696 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002697 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002698 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002699};
2700
Barry Warsawfa701a81997-01-16 00:15:11 +00002701
2702
Guido van Rossum18468821994-06-20 07:49:28 +00002703/**** Tkapp Type Methods ****/
2704
2705static void
Fred Drake509d79a2000-07-08 04:04:38 +00002706Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002707{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002708 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002709 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002710 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002711 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002712 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002713 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002714}
2715
Guido van Rossum18468821994-06-20 07:49:28 +00002716static PyTypeObject Tkapp_Type =
2717{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002718 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002719 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002720 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002721 0, /*tp_itemsize */
2722 Tkapp_Dealloc, /*tp_dealloc */
2723 0, /*tp_print */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002724 0, /*tp_getattr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002725 0, /*tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002726 0, /*tp_reserved */
Barry Warsawfa701a81997-01-16 00:15:11 +00002727 0, /*tp_repr */
2728 0, /*tp_as_number */
2729 0, /*tp_as_sequence */
2730 0, /*tp_as_mapping */
2731 0, /*tp_hash */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002732 0, /*tp_call*/
2733 0, /*tp_str*/
2734 0, /*tp_getattro*/
2735 0, /*tp_setattro*/
2736 0, /*tp_as_buffer*/
2737 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2738 0, /*tp_doc*/
2739 0, /*tp_traverse*/
2740 0, /*tp_clear*/
2741 0, /*tp_richcompare*/
2742 0, /*tp_weaklistoffset*/
2743 0, /*tp_iter*/
2744 0, /*tp_iternext*/
2745 Tkapp_methods, /*tp_methods*/
Guido van Rossum18468821994-06-20 07:49:28 +00002746};
2747
Barry Warsawfa701a81997-01-16 00:15:11 +00002748
2749
Guido van Rossum18468821994-06-20 07:49:28 +00002750/**** Tkinter Module ****/
2751
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002752typedef struct {
2753 PyObject* tuple;
2754 int size; /* current size */
2755 int maxsize; /* allocated size */
2756} FlattenContext;
2757
2758static int
2759_bump(FlattenContext* context, int size)
2760{
Guido van Rossum2834b972000-10-06 16:58:26 +00002761 /* expand tuple to hold (at least) size new items.
2762 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002763
2764 int maxsize = context->maxsize * 2;
2765
2766 if (maxsize < context->size + size)
2767 maxsize = context->size + size;
2768
2769 context->maxsize = maxsize;
2770
Tim Peters4324aa32001-05-28 22:30:08 +00002771 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002772}
2773
2774static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002775_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002776{
2777 /* add tuple or list to argument tuple (recursively) */
2778
2779 int i, size;
2780
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002781 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002782 PyErr_SetString(PyExc_ValueError,
2783 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002784 return 0;
2785 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002786 size = PyList_GET_SIZE(item);
2787 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002788 if (context->size + size > context->maxsize &&
2789 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002790 return 0;
2791 /* copy items to output tuple */
2792 for (i = 0; i < size; i++) {
2793 PyObject *o = PyList_GET_ITEM(item, i);
2794 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002795 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002796 return 0;
2797 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002798 if (context->size + 1 > context->maxsize &&
2799 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002800 return 0;
2801 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002802 PyTuple_SET_ITEM(context->tuple,
2803 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002804 }
2805 }
2806 } else if (PyTuple_Check(item)) {
2807 /* same, for tuples */
2808 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002809 if (context->size + size > context->maxsize &&
2810 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002811 return 0;
2812 for (i = 0; i < size; i++) {
2813 PyObject *o = PyTuple_GET_ITEM(item, i);
2814 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002815 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002816 return 0;
2817 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002818 if (context->size + 1 > context->maxsize &&
2819 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002820 return 0;
2821 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002822 PyTuple_SET_ITEM(context->tuple,
2823 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002824 }
2825 }
2826 } else {
2827 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2828 return 0;
2829 }
2830 return 1;
2831}
2832
2833static PyObject *
2834Tkinter_Flatten(PyObject* self, PyObject* args)
2835{
2836 FlattenContext context;
2837 PyObject* item;
2838
2839 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2840 return NULL;
2841
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002842 context.maxsize = PySequence_Size(item);
Benjamin Petersonc4bbc8d2009-01-30 03:39:35 +00002843 if (context.maxsize < 0)
2844 return NULL;
2845 if (context.maxsize == 0)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002846 return PyTuple_New(0);
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002847
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002848 context.tuple = PyTuple_New(context.maxsize);
2849 if (!context.tuple)
2850 return NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002851
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002852 context.size = 0;
2853
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002854 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002855 return NULL;
2856
Tim Peters4324aa32001-05-28 22:30:08 +00002857 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002858 return NULL;
2859
2860 return context.tuple;
2861}
2862
Guido van Rossum18468821994-06-20 07:49:28 +00002863static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002864Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002865{
Barry Warsawfa701a81997-01-16 00:15:11 +00002866 char *screenName = NULL;
Martin v. Löwisb9279bc2008-04-05 19:47:23 +00002867 char *baseName = NULL; /* XXX this is not used anymore;
2868 try getting rid of it. */
Barry Warsawfa701a81997-01-16 00:15:11 +00002869 char *className = NULL;
2870 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002871 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002872 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002873 int sync = 0; /* pass -sync to wish */
2874 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002875
Barry Warsawfa701a81997-01-16 00:15:11 +00002876 className = "Tk";
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002877
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002878 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002879 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002880 &interactive, &wantobjects, &wantTk,
2881 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00002882 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002883
Martin v. Löwisb9279bc2008-04-05 19:47:23 +00002884 return (PyObject *) Tkapp_New(screenName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002885 interactive, wantobjects, wantTk,
2886 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002887}
2888
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002889static PyObject *
2890Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2891{
2892 int new_val;
2893 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2894 return NULL;
2895 if (new_val < 0) {
2896 PyErr_SetString(PyExc_ValueError,
2897 "busywaitinterval must be >= 0");
2898 return NULL;
2899 }
2900 Tkinter_busywaitinterval = new_val;
2901 Py_INCREF(Py_None);
2902 return Py_None;
2903}
2904
2905static char setbusywaitinterval_doc[] =
2906"setbusywaitinterval(n) -> None\n\
2907\n\
2908Set the busy-wait interval in milliseconds between successive\n\
2909calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2910It should be set to a divisor of the maximum time between\n\
2911frames in an animation.";
2912
2913static PyObject *
2914Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2915{
Christian Heimes217cfd12007-12-02 14:31:20 +00002916 return PyLong_FromLong(Tkinter_busywaitinterval);
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002917}
2918
2919static char getbusywaitinterval_doc[] =
2920"getbusywaitinterval() -> int\n\
2921\n\
2922Return the current busy-wait interval between successive\n\
2923calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2924
Guido van Rossum18468821994-06-20 07:49:28 +00002925static PyMethodDef moduleMethods[] =
2926{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002927 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2928 {"create", Tkinter_Create, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002929 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2930 setbusywaitinterval_doc},
2931 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2932 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00002933 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002934};
2935
Guido van Rossum7bf15641998-05-22 18:28:17 +00002936#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002937
2938static int stdin_ready = 0;
2939
Guido van Rossumad4db171998-06-13 13:56:28 +00002940#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002941static void
Fred Drake509d79a2000-07-08 04:04:38 +00002942MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002943{
2944 stdin_ready = 1;
2945}
Guido van Rossumad4db171998-06-13 13:56:28 +00002946#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002947
Martin v. Löwisa9656492003-03-30 08:44:58 +00002948#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002949static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002950#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002951
Guido van Rossum18468821994-06-20 07:49:28 +00002952static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002953EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002954{
Guido van Rossumad4db171998-06-13 13:56:28 +00002955#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002956 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002957#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002958#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002959 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002960#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002961 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002962 errorInCmd = 0;
2963#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002964 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002965 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002966#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002967 while (!errorInCmd && !stdin_ready) {
2968 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002969#ifdef MS_WINDOWS
2970 if (_kbhit()) {
2971 stdin_ready = 1;
2972 break;
2973 }
2974#endif
2975#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002976 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002977 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002978 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002979
Guido van Rossum00d93061998-05-28 23:06:38 +00002980 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002981
2982 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002983 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002984 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002985 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00002986 Py_END_ALLOW_THREADS
2987#else
2988 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002989#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002990
2991 if (result < 0)
2992 break;
2993 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002994#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002995 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002996#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002997 if (errorInCmd) {
2998 errorInCmd = 0;
2999 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3000 excInCmd = valInCmd = trbInCmd = NULL;
3001 PyErr_Print();
3002 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003003#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003004 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003005#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003006 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00003007}
Guido van Rossum18468821994-06-20 07:49:28 +00003008
Guido van Rossum00d93061998-05-28 23:06:38 +00003009#endif
3010
Guido van Rossum7bf15641998-05-22 18:28:17 +00003011static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003012EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003013{
Guido van Rossum00d93061998-05-28 23:06:38 +00003014#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003015 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003016#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003017 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003018#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003019 PyOS_InputHook = EventHook;
3020 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003021#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003022}
3023
3024static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003025DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003026{
Guido van Rossum00d93061998-05-28 23:06:38 +00003027#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003028 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3029 PyOS_InputHook = NULL;
3030 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003031#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003032}
3033
Barry Warsawfa701a81997-01-16 00:15:11 +00003034
3035/* all errors will be checked in one fell swoop in init_tkinter() */
3036static void
Fred Drake509d79a2000-07-08 04:04:38 +00003037ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003038{
Christian Heimes217cfd12007-12-02 14:31:20 +00003039 PyObject *v = PyLong_FromLong(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003040 if (v) {
3041 PyDict_SetItemString(d, name, v);
3042 Py_DECREF(v);
3043 }
3044}
3045static void
Fred Drake509d79a2000-07-08 04:04:38 +00003046ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003047{
Martin v. Löwis4040fb82007-08-13 06:01:43 +00003048 PyObject *v = PyUnicode_FromString(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003049 if (v) {
3050 PyDict_SetItemString(d, name, v);
3051 Py_DECREF(v);
3052 }
3053}
3054
3055
Martin v. Löwis1a214512008-06-11 05:26:20 +00003056static struct PyModuleDef _tkintermodule = {
3057 PyModuleDef_HEAD_INIT,
3058 "_tkinter",
3059 NULL,
3060 -1,
3061 moduleMethods,
3062 NULL,
3063 NULL,
3064 NULL,
3065 NULL
3066};
3067
Mark Hammond62b1ab12002-07-23 06:31:15 +00003068PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00003069PyInit__tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003070{
Martin v. Löwis790465f2008-04-05 20:41:37 +00003071 PyObject *m, *d, *uexe, *cexe;
Guido van Rossum18468821994-06-20 07:49:28 +00003072
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00003073 if (PyType_Ready(&Tkapp_Type) < 0)
3074 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00003075
3076#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003077 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003078#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003079
Martin v. Löwis1a214512008-06-11 05:26:20 +00003080 m = PyModule_Create(&_tkintermodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003081 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00003082 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00003083
Barry Warsawfa701a81997-01-16 00:15:11 +00003084 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003085 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003086 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003087
Guido van Rossum35d43371997-08-02 00:09:09 +00003088 ins_long(d, "READABLE", TCL_READABLE);
3089 ins_long(d, "WRITABLE", TCL_WRITABLE);
3090 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3091 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3092 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3093 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3094 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3095 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3096 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003097 ins_string(d, "TK_VERSION", TK_VERSION);
3098 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003099
Guido van Rossum83551bf1997-09-13 00:44:23 +00003100 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003101
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00003102 if (PyType_Ready(&Tktt_Type) < 0)
3103 return NULL;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003104 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3105
Christian Heimes90aa7642007-12-19 02:45:37 +00003106 Py_TYPE(&PyTclObject_Type) = &PyType_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003107 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003108
3109#ifdef TK_AQUA
3110 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3111 * start waking up. Note that Tcl_FindExecutable will do this, this
3112 * code must be above it! The original warning from
3113 * tkMacOSXAppInit.c is copied below.
3114 *
3115 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3116 * Tcl interpreter for now. It probably should work to do this
3117 * in the other order, but for now it doesn't seem to.
3118 *
3119 */
3120 Tk_MacOSXSetupTkNotifier();
3121#endif
3122
3123
Guido van Rossume187b0e2000-03-27 21:46:29 +00003124 /* This helps the dynamic loader; in Unicode aware Tcl versions
3125 it also helps Tcl find its encodings. */
Martin v. Löwis790465f2008-04-05 20:41:37 +00003126 uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1);
3127 if (uexe) {
3128 cexe = PyUnicode_AsEncodedString(uexe,
3129 Py_FileSystemDefaultEncoding,
3130 NULL);
3131 if (cexe)
Christian Heimes72b710a2008-05-26 13:28:38 +00003132 Tcl_FindExecutable(PyBytes_AsString(cexe));
Martin v. Löwis790465f2008-04-05 20:41:37 +00003133 Py_XDECREF(cexe);
3134 Py_DECREF(uexe);
3135 }
Guido van Rossume187b0e2000-03-27 21:46:29 +00003136
Martin v. Löwis1a214512008-06-11 05:26:20 +00003137 if (PyErr_Occurred()) {
3138 Py_DECREF(m);
3139 return NULL;
3140 }
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003141
Guido van Rossum43ff8681998-07-14 18:02:13 +00003142#if 0
3143 /* This was not a good idea; through <Destroy> bindings,
3144 Tcl_Finalize() may invoke Python code but at that point the
3145 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003146 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003147#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +00003148 return m;
Guido van Rossum18468821994-06-20 07:49:28 +00003149}