blob: 645f9845fa0a406f85a6cff0f492dfc3be33988c [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
Martin v. Löwis39195712003-01-04 00:33:13 +000036/* Allow using this code in Python 2.[12] */
37#ifndef PyDoc_STRVAR
Martin v. Löwiscd9a8b62003-01-21 21:52:57 +000038#define PyDoc_STRVAR(name,str) static char name[] = str
Martin v. Löwis39195712003-01-04 00:33:13 +000039#endif
40
41#ifndef PyMODINIT_FUNC
Martin v. Löwis3a57d9d2003-01-04 08:54:59 +000042#define PyMODINIT_FUNC void
Martin v. Löwis39195712003-01-04 00:33:13 +000043#endif
44
Martin v. Löwis52ae6f62003-03-30 08:26:04 +000045#ifndef PyBool_Check
46#define PyBool_Check(o) 0
Christian Heimes217cfd12007-12-02 14:31:20 +000047#define PyBool_FromLong PyLong_FromLong
Martin v. Löwis52ae6f62003-03-30 08:26:04 +000048#endif
49
Martin v. Löwis71e25a02002-10-01 18:08:06 +000050/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
51 making _tkinter correct for this API means to break earlier
52 versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
53 earlier versions. Once Tcl releases before 8.4 don't need to be supported
54 anymore, this should go. */
55#define USE_COMPAT_CONST
56
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000057/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
58 it always; if Tcl is not threaded, the thread functions in
59 Tcl are empty. */
60#define TCL_THREADS
61
Jack Jansencb852442001-12-09 23:15:56 +000062#ifdef TK_FRAMEWORK
63#include <Tcl/tcl.h>
64#include <Tk/tk.h>
65#else
Guido van Rossum18468821994-06-20 07:49:28 +000066#include <tcl.h>
67#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000068#endif
Guido van Rossum18468821994-06-20 07:49:28 +000069
Jason Tishlerbbe89612002-12-31 20:30:46 +000070/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
Martin v. Löwis5b177f12002-12-30 18:14:15 +000071#ifndef CONST84_RETURN
72#define CONST84_RETURN
Jason Tishlerbbe89612002-12-31 20:30:46 +000073#undef CONST
Martin v. Löwis5b177f12002-12-30 18:14:15 +000074#define CONST
75#endif
76
Guido van Rossum3e819a71997-08-01 19:29:02 +000077#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
78
Martin v. Löwis6bfa2e62002-10-01 17:48:31 +000079#if TKMAJORMINOR < 8002
80#error "Tk older than 8.2 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000081#endif
82
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000083/* Unicode conversion assumes that Tcl_UniChar is two bytes.
84 We cannot test this directly, so we test UTF-8 size instead,
85 expecting that TCL_UTF_MAX is changed if Tcl ever supports
Guido van Rossum82c0dfa2007-11-21 20:09:18 +000086 either UTF-16 or UCS-4.
87 Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for
Martin v. Löwis6f29ff32003-04-16 20:34:55 +000088 Tcl_Unichar. This is also ok as long as Python uses UCS-4,
89 as well.
90*/
91#if TCL_UTF_MAX != 3 && !(defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==6)
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000092#error "unsupported Tcl configuration"
93#endif
94
Jack Janseneddc1442003-11-20 01:44:59 +000095#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
Guido van Rossum0d2390c1997-08-14 19:57:07 +000096#define HAVE_CREATEFILEHANDLER
97#endif
98
Guido van Rossum00d93061998-05-28 23:06:38 +000099#ifdef HAVE_CREATEFILEHANDLER
100
Neal Norwitzd948a432006-01-08 01:08:55 +0000101/* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere
102 with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */
103#ifndef TCL_UNIX_FD
104# ifdef TCL_WIN_SOCKET
105# define TCL_UNIX_FD (! TCL_WIN_SOCKET)
106# else
107# define TCL_UNIX_FD 1
108# endif
109#endif
110
Guido van Rossum00d93061998-05-28 23:06:38 +0000111/* Tcl_CreateFileHandler() changed several times; these macros deal with the
112 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
113 Unix, only because Jack added it back); when available on Windows, it only
114 applies to sockets. */
115
Guido van Rossum7bf15641998-05-22 18:28:17 +0000116#ifdef MS_WINDOWS
117#define FHANDLETYPE TCL_WIN_SOCKET
118#else
119#define FHANDLETYPE TCL_UNIX_FD
120#endif
121
Guido van Rossum00d93061998-05-28 23:06:38 +0000122/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
123 which uses this to handle Tcl events while the user is typing commands. */
124
125#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000126#define WAIT_FOR_STDIN
127#endif
128
Guido van Rossum00d93061998-05-28 23:06:38 +0000129#endif /* HAVE_CREATEFILEHANDLER */
130
Guido van Rossumad4db171998-06-13 13:56:28 +0000131#ifdef MS_WINDOWS
132#include <conio.h>
133#define WAIT_FOR_STDIN
134#endif
135
Guido van Rossum00d93061998-05-28 23:06:38 +0000136#ifdef WITH_THREAD
137
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000138/* The threading situation is complicated. Tcl is not thread-safe, except
139 when configured with --enable-threads.
Guido van Rossum00d93061998-05-28 23:06:38 +0000140 So we need to use a lock around all uses of Tcl. Previously, the Python
141 interpreter lock was used for this. However, this causes problems when
142 other Python threads need to run while Tcl is blocked waiting for events.
143
144 To solve this problem, a separate lock for Tcl is introduced. Holding it
145 is incompatible with holding Python's interpreter lock. The following four
146 macros manipulate both locks together.
147
148 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
149 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
150 that could call an event handler, or otherwise affect the state of a Tcl
151 interpreter. These assume that the surrounding code has the Python
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000152 interpreter lock; inside the brackets, the Python interpreter lock has been
Guido van Rossum00d93061998-05-28 23:06:38 +0000153 released and the lock for Tcl has been acquired.
154
Guido van Rossum5e977831998-06-15 14:03:52 +0000155 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
156 (For example, when transferring data from the Tcl interpreter result to a
157 Python string object.) This can be done by using different macros to close
158 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
159 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
160 releases the Tcl lock.
161
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000162 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000163 handlers when the handler needs to use Python. Such event handlers are
164 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000165 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000166 the Python interpreter lock, restoring the appropriate thread state, and
167 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
168 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000169 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000170
171 These locks expand to several statements and brackets; they should not be
172 used in branches of if statements and the like.
173
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000174 If Tcl is threaded, this approach won't work anymore. The Tcl interpreter is
175 only valid in the thread that created it, and all Tk activity must happen in this
176 thread, also. That means that the mainloop must be invoked in the thread that
177 created the interpreter. Invoking commands from other threads is possible;
178 _tkinter will queue an event for the interpreter thread, which will then
179 execute the command and pass back the result. If the main thread is not in the
180 mainloop, and invoking commands causes an exception; if the main loop is running
181 but not processing events, the command invocation will block.
182
183 In addition, for a threaded Tcl, a single global tcl_tstate won't be sufficient
184 anymore, since multiple Tcl interpreters may simultaneously dispatch in different
185 threads. So we use the Tcl TLS API.
186
Guido van Rossum00d93061998-05-28 23:06:38 +0000187*/
188
Guido van Rossum65d5b571998-12-21 19:32:43 +0000189static PyThread_type_lock tcl_lock = 0;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000190
191#ifdef TCL_THREADS
192static Tcl_ThreadDataKey state_key;
193typedef PyThreadState *ThreadSpecificData;
194#define tcl_tstate (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*)))
195#else
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000196static PyThreadState *tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000197#endif
Guido van Rossum00d93061998-05-28 23:06:38 +0000198
199#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000200 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000201 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000202
203#define LEAVE_TCL \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000204 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000205
Guido van Rossum62320c91998-06-15 04:36:09 +0000206#define ENTER_OVERLAP \
207 Py_END_ALLOW_THREADS
208
209#define LEAVE_OVERLAP_TCL \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000210 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000211
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000212#define ENTER_PYTHON \
213 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000214 if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000215
216#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000217 { PyThreadState *tstate = PyEval_SaveThread(); \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000218 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
219
220#define CHECK_TCL_APPARTMENT \
221 if (((TkappObject *)self)->threaded && \
222 ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
223 PyErr_SetString(PyExc_RuntimeError, "Calling Tcl from different appartment"); \
224 return 0; \
225 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000226
227#else
228
229#define ENTER_TCL
230#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000231#define ENTER_OVERLAP
232#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000233#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000234#define LEAVE_PYTHON
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000235#define CHECK_TCL_APPARTMENT
Guido van Rossum00d93061998-05-28 23:06:38 +0000236
237#endif
238
Guido van Rossum97867b21996-08-08 19:09:53 +0000239#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000240#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000241#endif
242
Guido van Rossum18468821994-06-20 07:49:28 +0000243/**** Tkapp Object Declaration ****/
244
Jeremy Hylton938ace62002-07-17 16:30:39 +0000245static PyTypeObject Tkapp_Type;
Guido van Rossum18468821994-06-20 07:49:28 +0000246
Guido van Rossum00d93061998-05-28 23:06:38 +0000247typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000248 PyObject_HEAD
249 Tcl_Interp *interp;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000250 int wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000251 int threaded; /* True if tcl_platform[threaded] */
252 Tcl_ThreadId thread_id;
253 int dispatching;
254 /* We cannot include tclInt.h, as this is internal.
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000255 So we cache interesting types here. */
256 Tcl_ObjType *BooleanType;
257 Tcl_ObjType *ByteArrayType;
258 Tcl_ObjType *DoubleType;
259 Tcl_ObjType *IntType;
260 Tcl_ObjType *ListType;
261 Tcl_ObjType *ProcBodyType;
262 Tcl_ObjType *StringType;
Guido van Rossum00d93061998-05-28 23:06:38 +0000263} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000264
Christian Heimes90aa7642007-12-19 02:45:37 +0000265#define Tkapp_Check(v) (Py_TYPE(v) == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000266#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000267#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000268
Guido van Rossum35d43371997-08-02 00:09:09 +0000269#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Christian Heimes90aa7642007-12-19 02:45:37 +0000270(void *) v, Py_REFCNT(v)))
Guido van Rossum18468821994-06-20 07:49:28 +0000271
Barry Warsawfa701a81997-01-16 00:15:11 +0000272
273
Guido van Rossum18468821994-06-20 07:49:28 +0000274/**** Error Handling ****/
275
276static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000277static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000278static int errorInCmd = 0;
279static PyObject *excInCmd;
280static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000282
Barry Warsawfa701a81997-01-16 00:15:11 +0000283
284
Guido van Rossum18468821994-06-20 07:49:28 +0000285static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000286Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000287{
Barry Warsawfa701a81997-01-16 00:15:11 +0000288 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
289 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000290}
291
Barry Warsawfa701a81997-01-16 00:15:11 +0000292
Barry Warsawfa701a81997-01-16 00:15:11 +0000293
Guido van Rossum18468821994-06-20 07:49:28 +0000294/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000295
Martin v. Löwis28e9ce92003-05-09 08:19:48 +0000296static int Tkinter_busywaitinterval = 20;
297
Guido van Rossum00d93061998-05-28 23:06:38 +0000298#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000299#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000300
Guido van Rossum00d93061998-05-28 23:06:38 +0000301/* Millisecond sleep() for Unix platforms. */
302
303static void
Fred Drake509d79a2000-07-08 04:04:38 +0000304Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000305{
306 /* XXX Too bad if you don't have select(). */
307 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000308 t.tv_sec = milli/1000;
309 t.tv_usec = (milli%1000) * 1000;
310 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
311}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000312#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000313
Martin v. Löwis5b26abb2002-12-28 09:23:09 +0000314/* Wait up to 1s for the mainloop to come up. */
315
316static int
317WaitForMainloop(TkappObject* self)
318{
319 int i;
320 for (i = 0; i < 10; i++) {
321 if (self->dispatching)
322 return 1;
323 Py_BEGIN_ALLOW_THREADS
324 Sleep(100);
325 Py_END_ALLOW_THREADS
326 }
327 if (self->dispatching)
328 return 1;
329 PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
330 return 0;
331}
Martin v. Löwisa9656492003-03-30 08:44:58 +0000332#endif /* WITH_THREAD */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000333
Guido van Rossum00d93061998-05-28 23:06:38 +0000334
Guido van Rossum18468821994-06-20 07:49:28 +0000335static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000336AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000337{
Christian Heimes72b710a2008-05-26 13:28:38 +0000338 if (PyBytes_Check(value))
339 return PyBytes_AsString(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000340 else if (PyUnicode_Check(value)) {
341 PyObject *v = PyUnicode_AsUTF8String(value);
342 if (v == NULL)
343 return NULL;
344 if (PyList_Append(tmp, v) != 0) {
345 Py_DECREF(v);
346 return NULL;
347 }
348 Py_DECREF(v);
Christian Heimes72b710a2008-05-26 13:28:38 +0000349 return PyBytes_AsString(v);
Guido van Rossum2834b972000-10-06 16:58:26 +0000350 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000351 else {
352 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000353 if (v == NULL)
354 return NULL;
355 if (PyList_Append(tmp, v) != 0) {
356 Py_DECREF(v);
357 return NULL;
358 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000359 Py_DECREF(v);
Christian Heimes72b710a2008-05-26 13:28:38 +0000360 return PyBytes_AsString(v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000361 }
Guido van Rossum18468821994-06-20 07:49:28 +0000362}
363
Barry Warsawfa701a81997-01-16 00:15:11 +0000364
365
Guido van Rossum18468821994-06-20 07:49:28 +0000366#define ARGSZ 64
367
368static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000369Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000370{
Barry Warsawfa701a81997-01-16 00:15:11 +0000371 PyObject *tmp = NULL;
372 char *argvStore[ARGSZ];
373 char **argv = NULL;
374 int fvStore[ARGSZ];
375 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000376 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000377 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000378
Barry Warsawfa701a81997-01-16 00:15:11 +0000379 if (!(tmp = PyList_New(0)))
380 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000381
Barry Warsawfa701a81997-01-16 00:15:11 +0000382 argv = argvStore;
383 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000384
Barry Warsawfa701a81997-01-16 00:15:11 +0000385 if (args == NULL)
386 argc = 0;
387
388 else if (!PyTuple_Check(args)) {
389 argc = 1;
390 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000391 if (!(argv[0] = AsString(args, tmp)))
392 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000393 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000394 else {
395 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000396
Barry Warsawfa701a81997-01-16 00:15:11 +0000397 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000398 argv = (char **)ckalloc(argc * sizeof(char *));
399 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 if (argv == NULL || fv == NULL) {
401 PyErr_NoMemory();
402 goto finally;
403 }
404 }
405
406 for (i = 0; i < argc; i++) {
407 PyObject *v = PyTuple_GetItem(args, i);
408 if (PyTuple_Check(v)) {
409 fv[i] = 1;
410 if (!(argv[i] = Merge(v)))
411 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000412 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000413 }
414 else if (v == Py_None) {
415 argc = i;
416 break;
417 }
418 else {
419 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000420 if (!(argv[i] = AsString(v, tmp)))
421 goto finally;
422 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000423 }
424 }
Guido van Rossum18468821994-06-20 07:49:28 +0000425 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000426 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000427 if (res == NULL)
428 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000429
Barry Warsawfa701a81997-01-16 00:15:11 +0000430 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000431 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000432 if (fv[i]) {
433 ckfree(argv[i]);
434 }
435 if (argv != argvStore)
436 ckfree(FREECAST argv);
437 if (fv != fvStore)
438 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000439
Barry Warsawfa701a81997-01-16 00:15:11 +0000440 Py_DECREF(tmp);
441 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000442}
443
Barry Warsawfa701a81997-01-16 00:15:11 +0000444
445
Guido van Rossum18468821994-06-20 07:49:28 +0000446static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000447Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000448{
Barry Warsawfa701a81997-01-16 00:15:11 +0000449 int argc;
450 char **argv;
451 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000452
Barry Warsawfa701a81997-01-16 00:15:11 +0000453 if (list == NULL) {
454 Py_INCREF(Py_None);
455 return Py_None;
456 }
Guido van Rossum18468821994-06-20 07:49:28 +0000457
Guido van Rossum00d93061998-05-28 23:06:38 +0000458 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000459 /* Not a list.
460 * Could be a quoted string containing funnies, e.g. {"}.
461 * Return the string itself.
462 */
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000463 return PyUnicode_FromString(list);
Barry Warsawfa701a81997-01-16 00:15:11 +0000464 }
Guido van Rossum18468821994-06-20 07:49:28 +0000465
Barry Warsawfa701a81997-01-16 00:15:11 +0000466 if (argc == 0)
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000467 v = PyUnicode_FromString("");
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 else if (argc == 1)
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000469 v = PyUnicode_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000470 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 int i;
472 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000473
Barry Warsawfa701a81997-01-16 00:15:11 +0000474 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000475 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 Py_DECREF(v);
477 v = NULL;
478 break;
479 }
480 PyTuple_SetItem(v, i, w);
481 }
482 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000483 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000484 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000485}
486
Martin v. Löwisffad6332002-11-26 09:28:05 +0000487/* In some cases, Tcl will still return strings that are supposed to be
488 lists. SplitObj walks through a nested tuple, finding string objects that
489 need to be split. */
490
Martin v. Löwis59683e82008-06-13 07:50:45 +0000491static PyObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000492SplitObj(PyObject *arg)
493{
494 if (PyTuple_Check(arg)) {
495 int i, size;
496 PyObject *elem, *newelem, *result;
497
498 size = PyTuple_Size(arg);
499 result = NULL;
500 /* Recursively invoke SplitObj for all tuple items.
501 If this does not return a new object, no action is
502 needed. */
503 for(i = 0; i < size; i++) {
504 elem = PyTuple_GetItem(arg, i);
505 newelem = SplitObj(elem);
506 if (!newelem) {
507 Py_XDECREF(result);
508 return NULL;
509 }
510 if (!result) {
511 int k;
512 if (newelem == elem) {
513 Py_DECREF(newelem);
514 continue;
515 }
516 result = PyTuple_New(size);
517 if (!result)
518 return NULL;
519 for(k = 0; k < i; k++) {
520 elem = PyTuple_GetItem(arg, k);
521 Py_INCREF(elem);
522 PyTuple_SetItem(result, k, elem);
523 }
524 }
525 PyTuple_SetItem(result, i, newelem);
526 }
527 if (result)
528 return result;
529 /* Fall through, returning arg. */
530 }
Christian Heimes72b710a2008-05-26 13:28:38 +0000531 else if (PyBytes_Check(arg)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000532 int argc;
533 char **argv;
Christian Heimes72b710a2008-05-26 13:28:38 +0000534 char *list = PyBytes_AsString(arg);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000535
536 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
537 Py_INCREF(arg);
538 return arg;
539 }
540 Tcl_Free(FREECAST argv);
541 if (argc > 1)
Christian Heimes72b710a2008-05-26 13:28:38 +0000542 return Split(PyBytes_AsString(arg));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000543 /* Fall through, returning arg. */
544 }
545 Py_INCREF(arg);
546 return arg;
547}
Barry Warsawfa701a81997-01-16 00:15:11 +0000548
549
Guido van Rossum18468821994-06-20 07:49:28 +0000550/**** Tkapp Object ****/
551
552#ifndef WITH_APPINIT
553int
Fred Drake509d79a2000-07-08 04:04:38 +0000554Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000555{
Barry Warsawfa701a81997-01-16 00:15:11 +0000556 Tk_Window main;
David Aschere2b4b322004-02-18 05:59:53 +0000557 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000558
Barry Warsawfa701a81997-01-16 00:15:11 +0000559 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000560 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000561 return TCL_ERROR;
562 }
David Aschere2b4b322004-02-18 05:59:53 +0000563 _tkinter_skip_tk_init = Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
564 if (_tkinter_skip_tk_init == NULL || strcmp(_tkinter_skip_tk_init, "1") != 0) {
565 main = Tk_MainWindow(interp);
566 if (Tk_Init(interp) == TCL_ERROR) {
567 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
568 return TCL_ERROR;
569 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 }
571 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000572}
573#endif /* !WITH_APPINIT */
574
Guido van Rossum18468821994-06-20 07:49:28 +0000575
Barry Warsawfa701a81997-01-16 00:15:11 +0000576
577
578/* Initialize the Tk application; see the `main' function in
579 * `tkMain.c'.
580 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000581
Thomas Wouters58d05102000-07-24 14:43:35 +0000582static void EnableEventHook(void); /* Forward */
583static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000584
Barry Warsawfa701a81997-01-16 00:15:11 +0000585static TkappObject *
Martin v. Löwisb9279bc2008-04-05 19:47:23 +0000586Tkapp_New(char *screenName, char *className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000587 int interactive, int wantobjects, int wantTk, int sync, char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000588{
589 TkappObject *v;
590 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000591
Guido van Rossumb18618d2000-05-03 23:44:39 +0000592 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000593 if (v == NULL)
594 return NULL;
595
596 v->interp = Tcl_CreateInterp();
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000597 v->wantobjects = wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000598 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
599 TCL_GLOBAL_ONLY) != NULL;
600 v->thread_id = Tcl_GetCurrentThread();
601 v->dispatching = 0;
602
603#ifndef TCL_THREADS
604 if (v->threaded) {
605 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
606 Py_DECREF(v);
607 return 0;
608 }
609#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000610#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000611 if (v->threaded && tcl_lock) {
612 /* If Tcl is threaded, we don't need the lock. */
613 PyThread_free_lock(tcl_lock);
614 tcl_lock = NULL;
615 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000616#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000617
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000618 v->BooleanType = Tcl_GetObjType("boolean");
619 v->ByteArrayType = Tcl_GetObjType("bytearray");
620 v->DoubleType = Tcl_GetObjType("double");
621 v->IntType = Tcl_GetObjType("int");
622 v->ListType = Tcl_GetObjType("list");
623 v->ProcBodyType = Tcl_GetObjType("procbody");
624 v->StringType = Tcl_GetObjType("string");
625
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000626 /* Delete the 'exit' command, which can screw things up */
627 Tcl_DeleteCommand(v->interp, "exit");
628
Barry Warsawfa701a81997-01-16 00:15:11 +0000629 if (screenName != NULL)
630 Tcl_SetVar2(v->interp, "env", "DISPLAY",
631 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000632
Barry Warsawfa701a81997-01-16 00:15:11 +0000633 if (interactive)
634 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
635 else
636 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000637
Barry Warsawfa701a81997-01-16 00:15:11 +0000638 /* This is used to get the application class for Tk 4.1 and up */
639 argv0 = (char*)ckalloc(strlen(className) + 1);
640 if (!argv0) {
641 PyErr_NoMemory();
642 Py_DECREF(v);
643 return NULL;
644 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000645
Barry Warsawfa701a81997-01-16 00:15:11 +0000646 strcpy(argv0, className);
Neal Norwitz9dbc7dd2005-12-19 06:08:59 +0000647 if (isupper(Py_CHARMASK(argv0[0])))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000648 argv0[0] = tolower(Py_CHARMASK(argv0[0]));
Barry Warsawfa701a81997-01-16 00:15:11 +0000649 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
650 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000651
David Aschere2b4b322004-02-18 05:59:53 +0000652 if (! wantTk) {
653 Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
654 }
655
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000656 /* some initial arguments need to be in argv */
657 if (sync || use) {
Tim Peters51fa3b72004-08-04 02:16:48 +0000658 char *args;
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000659 int len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000660
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000661 if (sync)
662 len += sizeof "-sync";
663 if (use)
664 len += strlen(use) + sizeof "-use ";
665
Tim Peters51fa3b72004-08-04 02:16:48 +0000666 args = (char*)ckalloc(len);
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000667 if (!args) {
668 PyErr_NoMemory();
669 Py_DECREF(v);
670 return NULL;
671 }
672
673 args[0] = '\0';
674 if (sync)
675 strcat(args, "-sync");
676 if (use) {
677 if (sync)
678 strcat(args, " ");
679 strcat(args, "-use ");
680 strcat(args, use);
681 }
682
683 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
684 ckfree(args);
685 }
686
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000687 if (Tcl_AppInit(v->interp) != TCL_OK) {
688 PyObject *result = Tkinter_Error((PyObject *)v);
689 Py_DECREF((PyObject *)v);
690 return (TkappObject *)result;
691 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000692
Guido van Rossum7bf15641998-05-22 18:28:17 +0000693 EnableEventHook();
694
Barry Warsawfa701a81997-01-16 00:15:11 +0000695 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000696}
697
Barry Warsawfa701a81997-01-16 00:15:11 +0000698
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000699static void
700Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
701 Tcl_Condition *cond, Tcl_Mutex *mutex)
702{
703 Py_BEGIN_ALLOW_THREADS;
704 Tcl_MutexLock(mutex);
705 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
706 Tcl_ThreadAlert(self->thread_id);
707 Tcl_ConditionWait(cond, mutex, NULL);
708 Tcl_MutexUnlock(mutex);
709 Py_END_ALLOW_THREADS
710}
711
Barry Warsawfa701a81997-01-16 00:15:11 +0000712
Guido van Rossum18468821994-06-20 07:49:28 +0000713/** Tcl Eval **/
714
Martin v. Löwisffad6332002-11-26 09:28:05 +0000715typedef struct {
716 PyObject_HEAD
717 Tcl_Obj *value;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000718 PyObject *string; /* This cannot cause cycles. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000719} PyTclObject;
720
Neal Norwitz227b5332006-03-22 09:28:35 +0000721static PyTypeObject PyTclObject_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000722#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
723
724static PyObject *
725newPyTclObject(Tcl_Obj *arg)
726{
727 PyTclObject *self;
728 self = PyObject_New(PyTclObject, &PyTclObject_Type);
729 if (self == NULL)
730 return NULL;
731 Tcl_IncrRefCount(arg);
732 self->value = arg;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000733 self->string = NULL;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000734 return (PyObject*)self;
735}
736
737static void
738PyTclObject_dealloc(PyTclObject *self)
739{
740 Tcl_DecrRefCount(self->value);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000741 Py_XDECREF(self->string);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000742 PyObject_Del(self);
743}
744
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000745static char*
746PyTclObject_TclString(PyObject *self)
747{
748 return Tcl_GetString(((PyTclObject*)self)->value);
749}
750
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000751/* Like _str, but create Unicode if necessary. */
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000752PyDoc_STRVAR(PyTclObject_string__doc__,
Christian Heimesb2b62622007-11-22 05:56:35 +0000753"the string representation of this object, either as str or bytes");
Martin v. Löwis39195712003-01-04 00:33:13 +0000754
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000755static PyObject *
756PyTclObject_string(PyTclObject *self, void *ignored)
757{
758 char *s;
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000759 int len;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000760 if (!self->string) {
761 s = Tcl_GetStringFromObj(self->value, &len);
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000762 self->string = PyUnicode_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000763 if (!self->string)
764 return NULL;
765 }
766 Py_INCREF(self->string);
767 return self->string;
768}
769
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000770static PyObject *
Walter Dörwald6720d912007-07-12 12:12:25 +0000771PyTclObject_str(PyTclObject *self, void *ignored)
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000772{
773 char *s;
774 int len;
775 if (self->string && PyUnicode_Check(self->string)) {
776 Py_INCREF(self->string);
777 return self->string;
778 }
779 /* XXX Could chache result if it is non-ASCII. */
780 s = Tcl_GetStringFromObj(self->value, &len);
781 return PyUnicode_DecodeUTF8(s, len, "strict");
782}
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000783
Martin v. Löwisffad6332002-11-26 09:28:05 +0000784static PyObject *
785PyTclObject_repr(PyTclObject *self)
786{
Walter Dörwald7569dfe2007-05-19 21:49:49 +0000787 return PyUnicode_FromFormat("<%s object at %p>",
788 self->value->typePtr->name, self->value);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000789}
790
Mark Dickinson211c6252009-02-01 10:28:51 +0000791#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
792
793static PyObject *
794PyTclObject_richcompare(PyObject *self, PyObject *other, int op)
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000795{
Mark Dickinson211c6252009-02-01 10:28:51 +0000796 int result;
797 PyObject *v;
798
799 /* neither argument should be NULL, unless something's gone wrong */
800 if (self == NULL || other == NULL) {
801 PyErr_BadInternalCall();
802 return NULL;
803 }
804
805 /* both arguments should be instances of PyTclObject */
806 if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) {
807 v = Py_NotImplemented;
808 goto finished;
809 }
810
811 if (self == other)
812 /* fast path when self and other are identical */
813 result = 0;
814 else
815 result = strcmp(Tcl_GetString(((PyTclObject *)self)->value),
816 Tcl_GetString(((PyTclObject *)other)->value));
817 /* Convert return value to a Boolean */
818 switch (op) {
819 case Py_EQ:
820 v = TEST_COND(result == 0);
821 break;
822 case Py_NE:
823 v = TEST_COND(result != 0);
824 break;
825 case Py_LE:
826 v = TEST_COND(result <= 0);
827 break;
828 case Py_GE:
829 v = TEST_COND(result >= 0);
830 break;
831 case Py_LT:
832 v = TEST_COND(result < 0);
833 break;
834 case Py_GT:
835 v = TEST_COND(result > 0);
836 break;
837 default:
838 PyErr_BadArgument();
839 return NULL;
840 }
841 finished:
842 Py_INCREF(v);
843 return v;
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000844}
845
Martin v. Löwis39195712003-01-04 00:33:13 +0000846PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
847
Martin v. Löwisffad6332002-11-26 09:28:05 +0000848static PyObject*
849get_typename(PyTclObject* obj, void* ignored)
850{
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000851 return PyUnicode_FromString(obj->value->typePtr->name);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000852}
853
Martin v. Löwis39195712003-01-04 00:33:13 +0000854
Martin v. Löwisffad6332002-11-26 09:28:05 +0000855static PyGetSetDef PyTclObject_getsetlist[] = {
Martin v. Löwis39195712003-01-04 00:33:13 +0000856 {"typename", (getter)get_typename, NULL, get_typename__doc__},
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000857 {"string", (getter)PyTclObject_string, NULL,
Martin v. Löwis39195712003-01-04 00:33:13 +0000858 PyTclObject_string__doc__},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000859 {0},
860};
861
Neal Norwitz227b5332006-03-22 09:28:35 +0000862static PyTypeObject PyTclObject_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000863 PyVarObject_HEAD_INIT(NULL, 0)
Martin v. Löwisffad6332002-11-26 09:28:05 +0000864 "_tkinter.Tcl_Obj", /*tp_name*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000865 sizeof(PyTclObject), /*tp_basicsize*/
866 0, /*tp_itemsize*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000867 /* methods */
Mark Dickinson211c6252009-02-01 10:28:51 +0000868 (destructor)PyTclObject_dealloc,/*tp_dealloc*/
869 0, /*tp_print*/
870 0, /*tp_getattr*/
871 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000872 0, /*tp_reserved*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000873 (reprfunc)PyTclObject_repr, /*tp_repr*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000874 0, /*tp_as_number*/
875 0, /*tp_as_sequence*/
876 0, /*tp_as_mapping*/
877 0, /*tp_hash*/
878 0, /*tp_call*/
879 (reprfunc)PyTclObject_str, /*tp_str*/
880 PyObject_GenericGetAttr, /*tp_getattro*/
881 0, /*tp_setattro*/
882 0, /*tp_as_buffer*/
883 Py_TPFLAGS_DEFAULT, /*tp_flags*/
884 0, /*tp_doc*/
885 0, /*tp_traverse*/
886 0, /*tp_clear*/
887 PyTclObject_richcompare, /*tp_richcompare*/
888 0, /*tp_weaklistoffset*/
889 0, /*tp_iter*/
890 0, /*tp_iternext*/
891 0, /*tp_methods*/
892 0, /*tp_members*/
893 PyTclObject_getsetlist, /*tp_getset*/
894 0, /*tp_base*/
895 0, /*tp_dict*/
896 0, /*tp_descr_get*/
897 0, /*tp_descr_set*/
898 0, /*tp_dictoffset*/
899 0, /*tp_init*/
900 0, /*tp_alloc*/
901 0, /*tp_new*/
902 0, /*tp_free*/
903 0, /*tp_is_gc*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000904};
905
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000906static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000907AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000908{
909 Tcl_Obj *result;
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +0000910 long longVal;
911 int overflow;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000912
Christian Heimes72b710a2008-05-26 13:28:38 +0000913 if (PyBytes_Check(value))
914 return Tcl_NewStringObj(PyBytes_AS_STRING(value),
915 PyBytes_GET_SIZE(value));
Martin v. Löwis70c3dda2003-01-22 09:17:38 +0000916 else if (PyBool_Check(value))
917 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +0000918 else if (PyLong_CheckExact(value) &&
919 ((longVal = PyLong_AsLongAndOverflow(value, &overflow)),
920 !overflow)) {
921 /* If there is an overflow in the long conversion,
922 fall through to default object handling. */
923 return Tcl_NewLongObj(longVal);
924 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000925 else if (PyFloat_Check(value))
926 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
927 else if (PyTuple_Check(value)) {
928 Tcl_Obj **argv = (Tcl_Obj**)
929 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
930 int i;
931 if(!argv)
932 return 0;
933 for(i=0;i<PyTuple_Size(value);i++)
934 argv[i] = AsObj(PyTuple_GetItem(value,i));
935 result = Tcl_NewListObj(PyTuple_Size(value), argv);
936 ckfree(FREECAST argv);
937 return result;
938 }
939 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000940 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000941 Py_ssize_t size = PyUnicode_GET_SIZE(value);
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000942 /* This #ifdef assumes that Tcl uses UCS-2.
943 See TCL_UTF_MAX test above. */
Martin v. Löwis6f29ff32003-04-16 20:34:55 +0000944#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
Christian Heimesa34706f2008-01-04 03:06:10 +0000945 Tcl_UniChar *outbuf = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000946 Py_ssize_t i;
Christian Heimesa34706f2008-01-04 03:06:10 +0000947 size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
948 if (allocsize >= size)
949 outbuf = (Tcl_UniChar*)ckalloc(allocsize);
950 /* Else overflow occurred, and we take the next exit */
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000951 if (!outbuf) {
952 PyErr_NoMemory();
953 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000954 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000955 for (i = 0; i < size; i++) {
956 if (inbuf[i] >= 0x10000) {
957 /* Tcl doesn't do UTF-16, yet. */
958 PyErr_SetString(PyExc_ValueError,
959 "unsupported character");
960 ckfree(FREECAST outbuf);
961 return NULL;
962 }
963 outbuf[i] = inbuf[i];
964 }
965 result = Tcl_NewUnicodeObj(outbuf, size);
966 ckfree(FREECAST outbuf);
967 return result;
968#else
969 return Tcl_NewUnicodeObj(inbuf, size);
970#endif
971
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000972 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000973 else if(PyTclObject_Check(value)) {
974 Tcl_Obj *v = ((PyTclObject*)value)->value;
975 Tcl_IncrRefCount(v);
976 return v;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000977 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000978 else {
979 PyObject *v = PyObject_Str(value);
980 if (!v)
981 return 0;
982 result = AsObj(v);
983 Py_DECREF(v);
984 return result;
985 }
986}
987
Martin v. Löwisffad6332002-11-26 09:28:05 +0000988static PyObject*
989FromObj(PyObject* tkapp, Tcl_Obj *value)
990{
991 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000992 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000993
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000994 if (value->typePtr == NULL) {
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000995 return PyUnicode_FromStringAndSize(value->bytes,
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000996 value->length);
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000997 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000998
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000999 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001000 result = value->internalRep.longValue ? Py_True : Py_False;
1001 Py_INCREF(result);
1002 return result;
1003 }
1004
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001005 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001006 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +00001007 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Christian Heimes72b710a2008-05-26 13:28:38 +00001008 return PyBytes_FromStringAndSize(data, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001009 }
1010
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001011 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001012 return PyFloat_FromDouble(value->internalRep.doubleValue);
1013 }
1014
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001015 if (value->typePtr == app->IntType) {
Christian Heimes217cfd12007-12-02 14:31:20 +00001016 return PyLong_FromLong(value->internalRep.longValue);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001017 }
1018
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001019 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001020 int size;
1021 int i, status;
1022 PyObject *elem;
1023 Tcl_Obj *tcl_elem;
1024
1025 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
1026 if (status == TCL_ERROR)
1027 return Tkinter_Error(tkapp);
1028 result = PyTuple_New(size);
1029 if (!result)
1030 return NULL;
1031 for (i = 0; i < size; i++) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001032 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
Martin v. Löwisffad6332002-11-26 09:28:05 +00001033 value, i, &tcl_elem);
1034 if (status == TCL_ERROR) {
1035 Py_DECREF(result);
1036 return Tkinter_Error(tkapp);
1037 }
1038 elem = FromObj(tkapp, tcl_elem);
1039 if (!elem) {
1040 Py_DECREF(result);
1041 return NULL;
1042 }
1043 PyTuple_SetItem(result, i, elem);
1044 }
1045 return result;
1046 }
1047
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001048 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001049 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +00001050 }
1051
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001052 if (value->typePtr == app->StringType) {
Martin v. Löwis6f29ff32003-04-16 20:34:55 +00001053#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
Martin v. Löwisffad6332002-11-26 09:28:05 +00001054 PyObject *result;
1055 int size;
1056 Tcl_UniChar *input;
1057 Py_UNICODE *output;
1058
1059 size = Tcl_GetCharLength(value);
1060 result = PyUnicode_FromUnicode(NULL, size);
1061 if (!result)
1062 return NULL;
1063 input = Tcl_GetUnicode(value);
1064 output = PyUnicode_AS_UNICODE(result);
1065 while (size--)
1066 *output++ = *input++;
1067 return result;
1068#else
1069 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1070 Tcl_GetCharLength(value));
1071#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +00001072 }
1073
1074 return newPyTclObject(value);
1075}
1076
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001077/* This mutex synchronizes inter-thread command calls. */
1078
1079TCL_DECLARE_MUTEX(call_mutex)
1080
1081typedef struct Tkapp_CallEvent {
1082 Tcl_Event ev; /* Must be first */
1083 TkappObject *self;
1084 PyObject *args;
1085 int flags;
1086 PyObject **res;
1087 PyObject **exc_type, **exc_value, **exc_tb;
Guilherme Polo491aee22009-02-06 23:16:11 +00001088 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001089} Tkapp_CallEvent;
1090
1091void
1092Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001093{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001094 int i;
1095 for (i = 0; i < objc; i++)
1096 Tcl_DecrRefCount(objv[i]);
1097 if (objv != objStore)
1098 ckfree(FREECAST objv);
1099}
Guido van Rossum18468821994-06-20 07:49:28 +00001100
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001101/* Convert Python objects to Tcl objects. This must happen in the
1102 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001103
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001104static Tcl_Obj**
1105Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1106{
1107 Tcl_Obj **objv = objStore;
Martin v. Löwis7d134952002-12-12 19:05:48 +00001108 int objc = 0, i;
Guido van Rossum212643f1998-04-29 16:22:14 +00001109 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +00001110 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001111
Guido van Rossum212643f1998-04-29 16:22:14 +00001112 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +00001113 objv[0] = AsObj(args);
1114 if (objv[0] == 0)
1115 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001116 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +00001117 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001118 }
1119 else {
Guido van Rossum632de272000-03-29 00:19:50 +00001120 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001121
Guido van Rossum632de272000-03-29 00:19:50 +00001122 if (objc > ARGSZ) {
1123 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1124 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001125 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +00001126 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +00001127 goto finally;
1128 }
1129 }
1130
Guido van Rossum632de272000-03-29 00:19:50 +00001131 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001132 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +00001133 if (v == Py_None) {
1134 objc = i;
1135 break;
1136 }
Guido van Rossum632de272000-03-29 00:19:50 +00001137 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +00001138 if (!objv[i]) {
1139 /* Reset objc, so it attempts to clear
1140 objects only up to i. */
1141 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +00001142 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001143 }
Guido van Rossum632de272000-03-29 00:19:50 +00001144 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001145 }
1146 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001147 *pobjc = objc;
1148 return objv;
1149finally:
1150 Tkapp_CallDeallocArgs(objv, objStore, objc);
1151 return NULL;
1152}
Guido van Rossum212643f1998-04-29 16:22:14 +00001153
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001154/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001155
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001156static PyObject*
1157Tkapp_CallResult(TkappObject *self)
1158{
1159 PyObject *res = NULL;
1160 if(self->wantobjects) {
1161 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001162 /* Not sure whether the IncrRef is necessary, but something
1163 may overwrite the interpreter result while we are
1164 converting it. */
1165 Tcl_IncrRefCount(value);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001166 res = FromObj((PyObject*)self, value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001167 Tcl_DecrRefCount(value);
1168 } else {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001169 const char *s = Tcl_GetStringResult(self->interp);
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001170 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001171
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001172 res = PyUnicode_FromStringAndSize(s, (int)(p-s));
Guido van Rossum990f5c62000-05-04 15:07:16 +00001173 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001174 return res;
1175}
Guido van Rossum632de272000-03-29 00:19:50 +00001176
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001177/* Tkapp_CallProc is the event procedure that is executed in the context of
1178 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1179 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001180
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001181static int
1182Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1183{
1184 Tcl_Obj *objStore[ARGSZ];
1185 Tcl_Obj **objv;
1186 int objc;
1187 int i;
1188 ENTER_PYTHON
1189 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1190 if (!objv) {
1191 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1192 *(e->res) = NULL;
1193 }
1194 LEAVE_PYTHON
1195 if (!objv)
1196 goto done;
1197 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1198 ENTER_PYTHON
1199 if (i == TCL_ERROR) {
1200 *(e->res) = NULL;
1201 *(e->exc_type) = NULL;
1202 *(e->exc_tb) = NULL;
1203 *(e->exc_value) = PyObject_CallFunction(
1204 Tkinter_TclError, "s",
1205 Tcl_GetStringResult(e->self->interp));
1206 }
1207 else {
1208 *(e->res) = Tkapp_CallResult(e->self);
1209 }
1210 LEAVE_PYTHON
Guilherme Polo491aee22009-02-06 23:16:11 +00001211
1212 Tkapp_CallDeallocArgs(objv, objStore, objc);
1213done:
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001214 /* Wake up calling thread. */
1215 Tcl_MutexLock(&call_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00001216 Tcl_ConditionNotify(e->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001217 Tcl_MutexUnlock(&call_mutex);
1218 return 1;
1219}
1220
1221/* This is the main entry point for calling a Tcl command.
1222 It supports three cases, with regard to threading:
1223 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1224 the context of the calling thread.
1225 2. Tcl is threaded, caller of the command is in the interpreter thread:
1226 Execute the command in the calling thread. Since the Tcl lock will
1227 not be used, we can merge that with case 1.
1228 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1229 the interpreter thread. Allocation of Tcl objects needs to occur in the
1230 interpreter thread, so we ship the PyObject* args to the target thread,
1231 and perform processing there. */
1232
1233static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001234Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001235{
1236 Tcl_Obj *objStore[ARGSZ];
1237 Tcl_Obj **objv = NULL;
1238 int objc, i;
1239 PyObject *res = NULL;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001240 TkappObject *self = (TkappObject*)selfptr;
Guilherme Polo7f423952009-02-02 21:17:09 +00001241 int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001242
Guido van Rossum992d4a32007-07-11 13:09:30 +00001243 /* If args is a single tuple, replace with contents of tuple */
1244 if (1 == PyTuple_Size(args)){
1245 PyObject* item = PyTuple_GetItem(args, 0);
1246 if (PyTuple_Check(item))
1247 args = item;
1248 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001249#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001250 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1251 /* We cannot call the command directly. Instead, we must
1252 marshal the parameters to the interpreter thread. */
1253 Tkapp_CallEvent *ev;
Guilherme Polo491aee22009-02-06 23:16:11 +00001254 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001255 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001256 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001257 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001258 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1259 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1260 ev->self = self;
1261 ev->args = args;
1262 ev->res = &res;
1263 ev->exc_type = &exc_type;
1264 ev->exc_value = &exc_value;
1265 ev->exc_tb = &exc_tb;
Guilherme Polo491aee22009-02-06 23:16:11 +00001266 ev->done = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001267
Guilherme Polo491aee22009-02-06 23:16:11 +00001268 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001269
1270 if (res == NULL) {
1271 if (exc_type)
1272 PyErr_Restore(exc_type, exc_value, exc_tb);
1273 else
1274 PyErr_SetObject(Tkinter_TclError, exc_value);
1275 }
Guilherme Polo491aee22009-02-06 23:16:11 +00001276 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001277 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001278 else
Martin v. Löwisa9656492003-03-30 08:44:58 +00001279#endif
1280 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001281
1282 objv = Tkapp_CallArgs(args, objStore, &objc);
1283 if (!objv)
1284 return NULL;
1285
1286 ENTER_TCL
1287
1288 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1289
1290 ENTER_OVERLAP
1291
1292 if (i == TCL_ERROR)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001293 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001294 else
1295 res = Tkapp_CallResult(self);
1296
1297 LEAVE_OVERLAP_TCL
1298
1299 Tkapp_CallDeallocArgs(objv, objStore, objc);
1300 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001301 return res;
1302}
1303
1304
1305static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001306Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001307{
Guido van Rossum212643f1998-04-29 16:22:14 +00001308 /* Could do the same here as for Tkapp_Call(), but this is not used
1309 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1310 way for the user to do what all its Global* variants do (save and
1311 reset the scope pointer, call the local version, restore the saved
1312 scope pointer). */
1313
Guido van Rossum62320c91998-06-15 04:36:09 +00001314 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001315 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001316
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001317 CHECK_TCL_APPARTMENT;
1318
Guido van Rossum62320c91998-06-15 04:36:09 +00001319 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001320 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001321 int err;
1322 ENTER_TCL
1323 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001324 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001325 if (err == TCL_ERROR)
1326 res = Tkinter_Error(self);
1327 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001328 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001329 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001330 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001331 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001332
1333 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001334}
1335
1336static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001337Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001338{
Barry Warsawfa701a81997-01-16 00:15:11 +00001339 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001340 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001341 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001342
Guido van Rossum43713e52000-02-29 13:59:29 +00001343 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001344 return NULL;
1345
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001346 CHECK_TCL_APPARTMENT;
1347
Guido van Rossum00d93061998-05-28 23:06:38 +00001348 ENTER_TCL
1349 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001350 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001351 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001352 res = Tkinter_Error(self);
1353 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001354 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001355 LEAVE_OVERLAP_TCL
1356 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001357}
1358
1359static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001360Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001361{
Barry Warsawfa701a81997-01-16 00:15:11 +00001362 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001363 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001364 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001365
Guido van Rossum43713e52000-02-29 13:59:29 +00001366 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001367 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001368
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001369 CHECK_TCL_APPARTMENT;
1370
Guido van Rossum00d93061998-05-28 23:06:38 +00001371 ENTER_TCL
1372 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001373 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001374 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001375 res = Tkinter_Error(self);
1376 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001377 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001378 LEAVE_OVERLAP_TCL
1379 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001380}
1381
1382static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001383Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001384{
Barry Warsawfa701a81997-01-16 00:15:11 +00001385 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001386 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001387 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001388
Guido van Rossum43713e52000-02-29 13:59:29 +00001389 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001390 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001391
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001392 CHECK_TCL_APPARTMENT;
1393
Guido van Rossum00d93061998-05-28 23:06:38 +00001394 ENTER_TCL
1395 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001396 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001397 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001398 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001399
Guido van Rossum62320c91998-06-15 04:36:09 +00001400 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001401 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001402 LEAVE_OVERLAP_TCL
1403 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001404}
1405
1406static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001407Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001408{
Barry Warsawfa701a81997-01-16 00:15:11 +00001409 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001410 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001411 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001412
Guido van Rossum35d43371997-08-02 00:09:09 +00001413 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001414 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001415
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001416 CHECK_TCL_APPARTMENT;
1417
Guido van Rossum00d93061998-05-28 23:06:38 +00001418 ENTER_TCL
1419 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001420 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001421 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001422 res = Tkinter_Error(self);
1423 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001424 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001425 LEAVE_OVERLAP_TCL
1426 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001427}
1428
1429static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001430Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001431{
Barry Warsawfa701a81997-01-16 00:15:11 +00001432 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001433
Guido van Rossum43713e52000-02-29 13:59:29 +00001434 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001435 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001436 CHECK_TCL_APPARTMENT;
1437
Guido van Rossum00d93061998-05-28 23:06:38 +00001438 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001439 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001440 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001441
Barry Warsawfa701a81997-01-16 00:15:11 +00001442 Py_INCREF(Py_None);
1443 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001444}
1445
Barry Warsawfa701a81997-01-16 00:15:11 +00001446
1447
Guido van Rossum18468821994-06-20 07:49:28 +00001448/** Tcl Variable **/
1449
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001450TCL_DECLARE_MUTEX(var_mutex)
1451
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001452typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001453typedef struct VarEvent {
1454 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001455 PyObject *self;
1456 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001457 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001458 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001459 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001460 PyObject **exc_type;
1461 PyObject **exc_val;
Guilherme Polo491aee22009-02-06 23:16:11 +00001462 Tcl_Condition *cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001463} VarEvent;
1464
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001465static int
1466varname_converter(PyObject *in, void *_out)
1467{
1468 char **out = (char**)_out;
Christian Heimes72b710a2008-05-26 13:28:38 +00001469 if (PyBytes_Check(in)) {
1470 *out = PyBytes_AsString(in);
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001471 return 1;
1472 }
Guido van Rossumf761e102007-07-23 18:34:37 +00001473 if (PyUnicode_Check(in)) {
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00001474 *out = _PyUnicode_AsString(in);
Guido van Rossumf761e102007-07-23 18:34:37 +00001475 return 1;
1476 }
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001477 if (PyTclObject_Check(in)) {
1478 *out = PyTclObject_TclString(in);
1479 return 1;
1480 }
1481 /* XXX: Should give diagnostics. */
1482 return 0;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001483}
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001484
Martin v. Löwis59683e82008-06-13 07:50:45 +00001485static void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001486var_perform(VarEvent *ev)
1487{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001488 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1489 if (!*(ev->res)) {
1490 PyObject *exc, *val, *tb;
1491 PyErr_Fetch(&exc, &val, &tb);
1492 PyErr_NormalizeException(&exc, &val, &tb);
1493 *(ev->exc_type) = exc;
1494 *(ev->exc_val) = val;
1495 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001496 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001497
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001498}
1499
1500static int
1501var_proc(VarEvent* ev, int flags)
1502{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001503 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001504 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001505 Tcl_MutexLock(&var_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00001506 Tcl_ConditionNotify(ev->cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001507 Tcl_MutexUnlock(&var_mutex);
1508 LEAVE_PYTHON
1509 return 1;
1510}
1511
1512static PyObject*
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001513var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001514{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001515 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisa9656492003-03-30 08:44:58 +00001516#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001517 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001518 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001519 VarEvent *ev;
1520 PyObject *res, *exc_type, *exc_val;
Guilherme Polo491aee22009-02-06 23:16:11 +00001521 Tcl_Condition cond = NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001522
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001523 /* The current thread is not the interpreter thread. Marshal
1524 the call to the interpreter thread, then wait for
1525 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001526 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001527 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001528
1529 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1530
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001531 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001532 ev->args = args;
1533 ev->flags = flags;
1534 ev->func = func;
1535 ev->res = &res;
1536 ev->exc_type = &exc_type;
1537 ev->exc_val = &exc_val;
Guilherme Polo491aee22009-02-06 23:16:11 +00001538 ev->cond = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001539 ev->ev.proc = (Tcl_EventProc*)var_proc;
Guilherme Polo491aee22009-02-06 23:16:11 +00001540 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
1541 Tcl_ConditionFinalize(&cond);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001542 if (!res) {
1543 PyErr_SetObject(exc_type, exc_val);
1544 Py_DECREF(exc_type);
1545 Py_DECREF(exc_val);
1546 return NULL;
1547 }
1548 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001549 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001550#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001551 /* Tcl is not threaded, or this is the interpreter thread. */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001552 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001553}
1554
Guido van Rossum18468821994-06-20 07:49:28 +00001555static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001556SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001557{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001558 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001559 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001560 PyObject *res = NULL;
1561 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001562
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001563 if (PyArg_ParseTuple(args, "O&O:setvar",
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001564 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001565 /* XXX Acquire tcl lock??? */
1566 newval = AsObj(newValue);
1567 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001568 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001569 ENTER_TCL
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001570 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001571 newval, flags);
1572 ENTER_OVERLAP
1573 if (!ok)
1574 Tkinter_Error(self);
1575 else {
1576 res = Py_None;
1577 Py_INCREF(res);
1578 }
1579 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001580 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001581 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001582 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001583 if (PyArg_ParseTuple(args, "ssO:setvar",
1584 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001585 /* XXX must hold tcl lock already??? */
1586 newval = AsObj(newValue);
1587 ENTER_TCL
1588 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1589 ENTER_OVERLAP
1590 if (!ok)
1591 Tkinter_Error(self);
1592 else {
1593 res = Py_None;
1594 Py_INCREF(res);
1595 }
1596 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001597 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001598 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001599 return NULL;
1600 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001601 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001602 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001603}
1604
1605static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001606Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001607{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001608 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001609}
1610
1611static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001612Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001613{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001614 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001615}
1616
Barry Warsawfa701a81997-01-16 00:15:11 +00001617
1618
Guido van Rossum18468821994-06-20 07:49:28 +00001619static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001620GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001621{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001622 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001623 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001624 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001625
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001626 if (!PyArg_ParseTuple(args, "O&|s:getvar",
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001627 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001628 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001629
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001630 ENTER_TCL
1631 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1632 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001633 if (tres == NULL) {
1634 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1635 } else {
1636 if (((TkappObject*)self)->wantobjects) {
1637 res = FromObj(self, tres);
1638 }
1639 else {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001640 res = PyUnicode_FromString(Tcl_GetString(tres));
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001641 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001642 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001643 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001644 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001645}
1646
1647static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001648Tkapp_GetVar(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(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001651}
1652
1653static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001654Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001655{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001656 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001657}
1658
Barry Warsawfa701a81997-01-16 00:15:11 +00001659
1660
Guido van Rossum18468821994-06-20 07:49:28 +00001661static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001662UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001663{
Guido van Rossum35d43371997-08-02 00:09:09 +00001664 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001665 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001666 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001667
Guido van Rossum43713e52000-02-29 13:59:29 +00001668 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001669 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001670
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001671 ENTER_TCL
1672 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1673 ENTER_OVERLAP
1674 if (code == TCL_ERROR)
1675 res = Tkinter_Error(self);
1676 else {
1677 Py_INCREF(Py_None);
1678 res = Py_None;
1679 }
1680 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001681 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001682}
1683
1684static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001685Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001686{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001687 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001688}
1689
1690static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001691Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001692{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001693 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001694}
1695
Barry Warsawfa701a81997-01-16 00:15:11 +00001696
1697
Guido van Rossum18468821994-06-20 07:49:28 +00001698/** Tcl to Python **/
1699
1700static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001701Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001702{
Barry Warsawfa701a81997-01-16 00:15:11 +00001703 char *s;
1704 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001705
Martin v. Löwisffad6332002-11-26 09:28:05 +00001706 if (PyTuple_Size(args) == 1) {
1707 PyObject* o = PyTuple_GetItem(args, 0);
Christian Heimes217cfd12007-12-02 14:31:20 +00001708 if (PyLong_Check(o)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001709 Py_INCREF(o);
1710 return o;
1711 }
1712 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001713 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001714 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001715 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001716 return Tkinter_Error(self);
1717 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001718}
1719
1720static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001721Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001722{
Barry Warsawfa701a81997-01-16 00:15:11 +00001723 char *s;
1724 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001725
Martin v. Löwisffad6332002-11-26 09:28:05 +00001726 if (PyTuple_Size(args) == 1) {
1727 PyObject *o = PyTuple_GetItem(args, 0);
1728 if (PyFloat_Check(o)) {
1729 Py_INCREF(o);
1730 return o;
1731 }
1732 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001733 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001734 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001735 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001736 return Tkinter_Error(self);
1737 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001738}
1739
1740static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001741Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001742{
Barry Warsawfa701a81997-01-16 00:15:11 +00001743 char *s;
1744 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001745
Martin v. Löwisffad6332002-11-26 09:28:05 +00001746 if (PyTuple_Size(args) == 1) {
1747 PyObject *o = PyTuple_GetItem(args, 0);
Christian Heimes217cfd12007-12-02 14:31:20 +00001748 if (PyLong_Check(o)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001749 Py_INCREF(o);
1750 return o;
1751 }
1752 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001753 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001754 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001755 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1756 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001757 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001758}
1759
1760static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001761Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001762{
Barry Warsawfa701a81997-01-16 00:15:11 +00001763 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001764 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001765 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001766
Guido van Rossum43713e52000-02-29 13:59:29 +00001767 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001768 return NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001769
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001770 CHECK_TCL_APPARTMENT;
1771
Guido van Rossum00d93061998-05-28 23:06:38 +00001772 ENTER_TCL
1773 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001774 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001775 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001776 res = Tkinter_Error(self);
1777 else
1778 res = Py_BuildValue("s", Tkapp_Result(self));
1779 LEAVE_OVERLAP_TCL
1780 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001781}
1782
1783static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001784Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001785{
Barry Warsawfa701a81997-01-16 00:15:11 +00001786 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001787 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001788 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001789 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001790
Guido van Rossum43713e52000-02-29 13:59:29 +00001791 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001792 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001793
1794 CHECK_TCL_APPARTMENT;
1795
Guido van Rossum00d93061998-05-28 23:06:38 +00001796 ENTER_TCL
1797 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001798 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001799 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001800 res = Tkinter_Error(self);
1801 else
1802 res = Py_BuildValue("l", v);
1803 LEAVE_OVERLAP_TCL
1804 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001805}
1806
1807static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001808Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001809{
Barry Warsawfa701a81997-01-16 00:15:11 +00001810 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001811 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001812 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001813 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001814
Guido van Rossum43713e52000-02-29 13:59:29 +00001815 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001816 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001817 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001818 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001819 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001820 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001821 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001822 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001823 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001824 res = Tkinter_Error(self);
1825 else
1826 res = Py_BuildValue("d", v);
1827 LEAVE_OVERLAP_TCL
1828 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001829}
1830
1831static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001832Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001833{
Barry Warsawfa701a81997-01-16 00:15:11 +00001834 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001835 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001836 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001837 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001838
Guido van Rossum43713e52000-02-29 13:59:29 +00001839 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001840 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001841 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001842 ENTER_TCL
1843 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001844 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001845 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001846 res = Tkinter_Error(self);
1847 else
1848 res = Py_BuildValue("i", v);
1849 LEAVE_OVERLAP_TCL
1850 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001851}
1852
Barry Warsawfa701a81997-01-16 00:15:11 +00001853
1854
Guido van Rossum18468821994-06-20 07:49:28 +00001855static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001856Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001857{
Barry Warsawfa701a81997-01-16 00:15:11 +00001858 char *list;
1859 int argc;
1860 char **argv;
1861 PyObject *v;
1862 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001863
Martin v. Löwisffad6332002-11-26 09:28:05 +00001864 if (PyTuple_Size(args) == 1) {
1865 v = PyTuple_GetItem(args, 0);
1866 if (PyTuple_Check(v)) {
1867 Py_INCREF(v);
1868 return v;
1869 }
1870 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001871 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001872 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001873
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001874 if (Tcl_SplitList(Tkapp_Interp(self), list,
Neal Norwitzd1c55102003-05-29 00:17:03 +00001875 &argc, &argv) == TCL_ERROR) {
1876 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001877 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001878 }
Guido van Rossum18468821994-06-20 07:49:28 +00001879
Barry Warsawfa701a81997-01-16 00:15:11 +00001880 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001881 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001882
Barry Warsawfa701a81997-01-16 00:15:11 +00001883 for (i = 0; i < argc; i++) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001884 PyObject *s = PyUnicode_FromString(argv[i]);
Barry Warsawfa701a81997-01-16 00:15:11 +00001885 if (!s || PyTuple_SetItem(v, i, s)) {
1886 Py_DECREF(v);
1887 v = NULL;
1888 goto finally;
1889 }
1890 }
Guido van Rossum18468821994-06-20 07:49:28 +00001891
Barry Warsawfa701a81997-01-16 00:15:11 +00001892 finally:
1893 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001894 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001895 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001896}
1897
1898static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001899Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001900{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001901 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001902 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001903
Martin v. Löwisffad6332002-11-26 09:28:05 +00001904 if (PyTuple_Size(args) == 1) {
1905 PyObject* o = PyTuple_GetItem(args, 0);
1906 if (PyTuple_Check(o)) {
1907 o = SplitObj(o);
1908 return o;
1909 }
1910 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001911 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001912 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00001913 v = Split(list);
1914 PyMem_Free(list);
1915 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001916}
1917
1918static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001919Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001920{
Barry Warsawfa701a81997-01-16 00:15:11 +00001921 char *s = Merge(args);
1922 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001923
Barry Warsawfa701a81997-01-16 00:15:11 +00001924 if (s) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001925 res = PyUnicode_FromString(s);
Barry Warsawfa701a81997-01-16 00:15:11 +00001926 ckfree(s);
1927 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001928
1929 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001930}
1931
Barry Warsawfa701a81997-01-16 00:15:11 +00001932
1933
Guido van Rossum18468821994-06-20 07:49:28 +00001934/** Tcl Command **/
1935
Guido van Rossum00d93061998-05-28 23:06:38 +00001936/* Client data struct */
1937typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001938 PyObject *self;
1939 PyObject *func;
1940} PythonCmd_ClientData;
1941
1942static int
Fred Drake509d79a2000-07-08 04:04:38 +00001943PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001944{
1945 errorInCmd = 1;
1946 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1947 LEAVE_PYTHON
1948 return TCL_ERROR;
1949}
1950
Guido van Rossum18468821994-06-20 07:49:28 +00001951/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001952 * function or method.
1953 */
Guido van Rossum18468821994-06-20 07:49:28 +00001954static int
Fred Drake509d79a2000-07-08 04:04:38 +00001955PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001956{
Guido van Rossum00d93061998-05-28 23:06:38 +00001957 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Hirokazu Yamamotode603472008-11-18 04:33:04 +00001958 PyObject *self, *func, *arg, *res;
Guido van Rossum2834b972000-10-06 16:58:26 +00001959 int i, rv;
Christian Heimes57dddfb2008-01-02 18:30:52 +00001960 Tcl_Obj *obj_res;
Guido van Rossum18468821994-06-20 07:49:28 +00001961
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001962 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001963
Barry Warsawfa701a81997-01-16 00:15:11 +00001964 /* TBD: no error checking here since we know, via the
1965 * Tkapp_CreateCommand() that the client data is a two-tuple
1966 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001967 self = data->self;
1968 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001969
Barry Warsawfa701a81997-01-16 00:15:11 +00001970 /* Create argument list (argv1, ..., argvN) */
1971 if (!(arg = PyTuple_New(argc - 1)))
1972 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001973
Barry Warsawfa701a81997-01-16 00:15:11 +00001974 for (i = 0; i < (argc - 1); i++) {
Hirokazu Yamamotode603472008-11-18 04:33:04 +00001975 PyObject *s = PyUnicode_FromString(argv[i + 1]);
Barry Warsawfa701a81997-01-16 00:15:11 +00001976 if (!s || PyTuple_SetItem(arg, i, s)) {
1977 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001978 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001979 }
1980 }
1981 res = PyEval_CallObject(func, arg);
1982 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001983
Barry Warsawfa701a81997-01-16 00:15:11 +00001984 if (res == NULL)
1985 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001986
Christian Heimes57dddfb2008-01-02 18:30:52 +00001987 obj_res = AsObj(res);
1988 if (obj_res == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001989 Py_DECREF(res);
1990 return PythonCmd_Error(interp);
1991 }
Guido van Rossum2834b972000-10-06 16:58:26 +00001992 else {
Christian Heimes57dddfb2008-01-02 18:30:52 +00001993 Tcl_SetObjResult(Tkapp_Interp(self), obj_res);
Guido van Rossum2834b972000-10-06 16:58:26 +00001994 rv = TCL_OK;
1995 }
1996
Barry Warsawfa701a81997-01-16 00:15:11 +00001997 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00001998
Guido van Rossum00d93061998-05-28 23:06:38 +00001999 LEAVE_PYTHON
2000
Guido van Rossum2834b972000-10-06 16:58:26 +00002001 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002002}
2003
2004static void
Fred Drake509d79a2000-07-08 04:04:38 +00002005PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002006{
Guido van Rossum00d93061998-05-28 23:06:38 +00002007 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2008
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002009 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002010 Py_XDECREF(data->self);
2011 Py_XDECREF(data->func);
2012 PyMem_DEL(data);
2013 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002014}
2015
Barry Warsawfa701a81997-01-16 00:15:11 +00002016
2017
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002018
2019TCL_DECLARE_MUTEX(command_mutex)
2020
2021typedef struct CommandEvent{
2022 Tcl_Event ev;
2023 Tcl_Interp* interp;
2024 char *name;
2025 int create;
2026 int *status;
2027 ClientData *data;
Guilherme Polo491aee22009-02-06 23:16:11 +00002028 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002029} CommandEvent;
2030
2031static int
2032Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002033{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002034 if (ev->create)
2035 *ev->status = Tcl_CreateCommand(
2036 ev->interp, ev->name, PythonCmd,
2037 ev->data, PythonCmdDelete) == NULL;
2038 else
2039 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2040 Tcl_MutexLock(&command_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00002041 Tcl_ConditionNotify(ev->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002042 Tcl_MutexUnlock(&command_mutex);
2043 return 1;
2044}
2045
2046static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002047Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002048{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002049 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002050 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002051 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002052 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002053 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002054
Guido van Rossum43713e52000-02-29 13:59:29 +00002055 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002056 return NULL;
2057 if (!PyCallable_Check(func)) {
2058 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002059 return NULL;
2060 }
Guido van Rossum18468821994-06-20 07:49:28 +00002061
Martin v. Löwisa9656492003-03-30 08:44:58 +00002062#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002063 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002064 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002065 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002066#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002067
Guido van Rossum00d93061998-05-28 23:06:38 +00002068 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002069 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002070 return PyErr_NoMemory();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002071 Py_INCREF(self);
2072 Py_INCREF(func);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002073 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002074 data->func = func;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002075
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002076 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo491aee22009-02-06 23:16:11 +00002077 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002078 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2079 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2080 ev->interp = self->interp;
2081 ev->create = 1;
2082 ev->name = cmdName;
2083 ev->data = (ClientData)data;
2084 ev->status = &err;
Guilherme Polo491aee22009-02-06 23:16:11 +00002085 ev->done = &cond;
2086 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
2087 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002088 }
2089 else {
2090 ENTER_TCL
2091 err = Tcl_CreateCommand(
2092 Tkapp_Interp(self), cmdName, PythonCmd,
2093 (ClientData)data, PythonCmdDelete) == NULL;
2094 LEAVE_TCL
2095 }
2096 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002097 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002098 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002099 return NULL;
2100 }
Guido van Rossum18468821994-06-20 07:49:28 +00002101
Barry Warsawfa701a81997-01-16 00:15:11 +00002102 Py_INCREF(Py_None);
2103 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002104}
2105
Barry Warsawfa701a81997-01-16 00:15:11 +00002106
2107
Guido van Rossum18468821994-06-20 07:49:28 +00002108static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002109Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002110{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002111 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002112 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002113 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002114
Guido van Rossum43713e52000-02-29 13:59:29 +00002115 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002116 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002117 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo491aee22009-02-06 23:16:11 +00002118 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002119 CommandEvent *ev;
2120 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2121 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2122 ev->interp = self->interp;
2123 ev->create = 0;
2124 ev->name = cmdName;
2125 ev->status = &err;
Guilherme Polo491aee22009-02-06 23:16:11 +00002126 ev->done = &cond;
2127 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002128 &command_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00002129 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002130 }
2131 else {
2132 ENTER_TCL
2133 err = Tcl_DeleteCommand(self->interp, cmdName);
2134 LEAVE_TCL
2135 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002136 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002137 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2138 return NULL;
2139 }
2140 Py_INCREF(Py_None);
2141 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002142}
2143
Barry Warsawfa701a81997-01-16 00:15:11 +00002144
2145
Guido van Rossum00d93061998-05-28 23:06:38 +00002146#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002147/** File Handler **/
2148
Guido van Rossum00d93061998-05-28 23:06:38 +00002149typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002150 PyObject *func;
2151 PyObject *file;
2152 int id;
2153 struct _fhcdata *next;
2154} FileHandler_ClientData;
2155
2156static FileHandler_ClientData *HeadFHCD;
2157
2158static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002159NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002160{
2161 FileHandler_ClientData *p;
2162 p = PyMem_NEW(FileHandler_ClientData, 1);
2163 if (p != NULL) {
2164 Py_XINCREF(func);
2165 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002166 p->func = func;
2167 p->file = file;
2168 p->id = id;
2169 p->next = HeadFHCD;
2170 HeadFHCD = p;
2171 }
2172 return p;
2173}
2174
2175static void
Fred Drake509d79a2000-07-08 04:04:38 +00002176DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002177{
2178 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002179
2180 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002181 while ((p = *pp) != NULL) {
2182 if (p->id == id) {
2183 *pp = p->next;
2184 Py_XDECREF(p->func);
2185 Py_XDECREF(p->file);
2186 PyMem_DEL(p);
2187 }
2188 else
2189 pp = &p->next;
2190 }
2191}
2192
Guido van Rossuma597dde1995-01-10 20:56:29 +00002193static void
Fred Drake509d79a2000-07-08 04:04:38 +00002194FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002195{
Guido van Rossum00d93061998-05-28 23:06:38 +00002196 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002197 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002198
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002199 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002200 func = data->func;
2201 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002202
Barry Warsawfa701a81997-01-16 00:15:11 +00002203 arg = Py_BuildValue("(Oi)", file, (long) mask);
2204 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002205 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002206
2207 if (res == NULL) {
2208 errorInCmd = 1;
2209 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2210 }
2211 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002212 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002213}
2214
Guido van Rossum18468821994-06-20 07:49:28 +00002215static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002216Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2217 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002218{
Guido van Rossum00d93061998-05-28 23:06:38 +00002219 FileHandler_ClientData *data;
2220 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002221 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002222
Guido van Rossum2834b972000-10-06 16:58:26 +00002223 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2224 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002225 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002226
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002227 CHECK_TCL_APPARTMENT;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002228
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002229 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002230 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002231 return NULL;
2232 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002233 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002234 return NULL;
2235 }
2236
Guido van Rossuma80649b2000-03-28 20:07:05 +00002237 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002238 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002239 return NULL;
2240
Barry Warsawfa701a81997-01-16 00:15:11 +00002241 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002242 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002243 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002244 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002245 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002246 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002247}
2248
2249static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002250Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002251{
Barry Warsawfa701a81997-01-16 00:15:11 +00002252 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002253 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002254
Guido van Rossum43713e52000-02-29 13:59:29 +00002255 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002256 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002257
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002258 CHECK_TCL_APPARTMENT;
Neal Norwitz12e22172003-03-03 21:16:39 +00002259
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002260 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002261 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002262 return NULL;
2263
Guido van Rossuma80649b2000-03-28 20:07:05 +00002264 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002265
Barry Warsawfa701a81997-01-16 00:15:11 +00002266 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002267 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002268 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002269 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002270 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002271 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002272}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002273#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002274
Barry Warsawfa701a81997-01-16 00:15:11 +00002275
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002276/**** Tktt Object (timer token) ****/
2277
Jeremy Hylton938ace62002-07-17 16:30:39 +00002278static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002279
Guido van Rossum00d93061998-05-28 23:06:38 +00002280typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002281 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002282 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002283 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002284} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002285
2286static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002287Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002288{
Barry Warsawfa701a81997-01-16 00:15:11 +00002289 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002290 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002291
Guido van Rossum43713e52000-02-29 13:59:29 +00002292 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002293 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002294 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002295 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002296 v->token = NULL;
2297 }
2298 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002299 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002300 Py_DECREF(func);
2301 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002302 }
2303 Py_INCREF(Py_None);
2304 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002305}
2306
2307static PyMethodDef Tktt_methods[] =
2308{
Neal Norwitzb0493252002-03-31 14:44:22 +00002309 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002310 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002311};
2312
2313static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002314Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002315{
Barry Warsawfa701a81997-01-16 00:15:11 +00002316 TkttObject *v;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002317
Guido van Rossumb18618d2000-05-03 23:44:39 +00002318 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002319 if (v == NULL)
2320 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002321
Guido van Rossum00d93061998-05-28 23:06:38 +00002322 Py_INCREF(func);
2323 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002324 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002325
2326 /* Extra reference, deleted when called or when handler is deleted */
2327 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002328 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002329}
2330
2331static void
Fred Drake509d79a2000-07-08 04:04:38 +00002332Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002333{
Guido van Rossum00d93061998-05-28 23:06:38 +00002334 TkttObject *v = (TkttObject *)self;
2335 PyObject *func = v->func;
2336
2337 Py_XDECREF(func);
2338
Guido van Rossumb18618d2000-05-03 23:44:39 +00002339 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002340}
2341
Guido van Rossum597ac201998-05-12 14:36:19 +00002342static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002343Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002344{
Barry Warsawfa701a81997-01-16 00:15:11 +00002345 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002346 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002347
Tim Peters885d4572001-11-28 20:27:42 +00002348 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002349 v->func == NULL ? ", handler deleted" : "");
Walter Dörwald1ab83302007-05-18 17:15:44 +00002350 return PyUnicode_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002351}
2352
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002353static PyTypeObject Tktt_Type =
2354{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002355 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002356 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002357 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002358 0, /*tp_itemsize */
2359 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002360 0, /*tp_print */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002361 0, /*tp_getattr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002362 0, /*tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002363 0, /*tp_reserved */
Guido van Rossum597ac201998-05-12 14:36:19 +00002364 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002365 0, /*tp_as_number */
2366 0, /*tp_as_sequence */
2367 0, /*tp_as_mapping */
2368 0, /*tp_hash */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002369 0, /*tp_call*/
2370 0, /*tp_str*/
2371 0, /*tp_getattro*/
2372 0, /*tp_setattro*/
2373 0, /*tp_as_buffer*/
2374 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2375 0, /*tp_doc*/
2376 0, /*tp_traverse*/
2377 0, /*tp_clear*/
2378 0, /*tp_richcompare*/
2379 0, /*tp_weaklistoffset*/
2380 0, /*tp_iter*/
2381 0, /*tp_iternext*/
2382 Tktt_methods, /*tp_methods*/
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002383};
2384
Barry Warsawfa701a81997-01-16 00:15:11 +00002385
2386
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002387/** Timer Handler **/
2388
2389static void
Fred Drake509d79a2000-07-08 04:04:38 +00002390TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002391{
Guido van Rossum00d93061998-05-28 23:06:38 +00002392 TkttObject *v = (TkttObject *)clientData;
2393 PyObject *func = v->func;
2394 PyObject *res;
2395
2396 if (func == NULL)
2397 return;
2398
2399 v->func = NULL;
2400
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002401 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002402
2403 res = PyEval_CallObject(func, NULL);
2404 Py_DECREF(func);
2405 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002406
Barry Warsawfa701a81997-01-16 00:15:11 +00002407 if (res == NULL) {
2408 errorInCmd = 1;
2409 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2410 }
2411 else
2412 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002413
2414 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002415}
2416
2417static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002418Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002419{
Barry Warsawfa701a81997-01-16 00:15:11 +00002420 int milliseconds;
2421 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002422 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002423
Guido van Rossum2834b972000-10-06 16:58:26 +00002424 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2425 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002426 return NULL;
2427 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002428 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002429 return NULL;
2430 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002431
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002432 CHECK_TCL_APPARTMENT;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002433
Guido van Rossum00d93061998-05-28 23:06:38 +00002434 v = Tktt_New(func);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002435 if (v) {
2436 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2437 (ClientData)v);
2438 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002439
Guido van Rossum00d93061998-05-28 23:06:38 +00002440 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002441}
2442
Barry Warsawfa701a81997-01-16 00:15:11 +00002443
Guido van Rossum18468821994-06-20 07:49:28 +00002444/** Event Loop **/
2445
Guido van Rossum18468821994-06-20 07:49:28 +00002446static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002447Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002448{
Barry Warsawfa701a81997-01-16 00:15:11 +00002449 int threshold = 0;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002450 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002451#ifdef WITH_THREAD
2452 PyThreadState *tstate = PyThreadState_Get();
2453#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002454
Guido van Rossum43713e52000-02-29 13:59:29 +00002455 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002456 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002457
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002458 CHECK_TCL_APPARTMENT;
2459 self->dispatching = 1;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002460
Barry Warsawfa701a81997-01-16 00:15:11 +00002461 quitMainLoop = 0;
2462 while (Tk_GetNumMainWindows() > threshold &&
2463 !quitMainLoop &&
2464 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002465 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002466 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002467
2468#ifdef WITH_THREAD
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002469 if (self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002470 /* Allow other Python threads to run. */
2471 ENTER_TCL
2472 result = Tcl_DoOneEvent(0);
2473 LEAVE_TCL
2474 }
2475 else {
2476 Py_BEGIN_ALLOW_THREADS
2477 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2478 tcl_tstate = tstate;
2479 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2480 tcl_tstate = NULL;
2481 if(tcl_lock)PyThread_release_lock(tcl_lock);
2482 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002483 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002484 Py_END_ALLOW_THREADS
2485 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002486#else
2487 result = Tcl_DoOneEvent(0);
2488#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002489
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002490 if (PyErr_CheckSignals() != 0) {
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002491 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002492 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002493 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002494 if (result < 0)
2495 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002496 }
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002497 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002498 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002499
Barry Warsawfa701a81997-01-16 00:15:11 +00002500 if (errorInCmd) {
2501 errorInCmd = 0;
2502 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2503 excInCmd = valInCmd = trbInCmd = NULL;
2504 return NULL;
2505 }
2506 Py_INCREF(Py_None);
2507 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002508}
2509
2510static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002511Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002512{
Guido van Rossum35d43371997-08-02 00:09:09 +00002513 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002514 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002515
Guido van Rossum43713e52000-02-29 13:59:29 +00002516 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002517 return NULL;
2518
Guido van Rossum00d93061998-05-28 23:06:38 +00002519 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002520 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002521 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002522 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002523}
2524
2525static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002526Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002527{
2528
Guido van Rossum43713e52000-02-29 13:59:29 +00002529 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002530 return NULL;
2531
2532 quitMainLoop = 1;
2533 Py_INCREF(Py_None);
2534 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002535}
2536
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002537static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002538Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002539{
2540
Guido van Rossum43713e52000-02-29 13:59:29 +00002541 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002542 return NULL;
2543
Christian Heimes217cfd12007-12-02 14:31:20 +00002544 return PyLong_FromLong((long)Tkapp_Interp(self));
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002545}
2546
David Aschere2b4b322004-02-18 05:59:53 +00002547static PyObject *
2548Tkapp_TkInit(PyObject *self, PyObject *args)
2549{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002550 static int has_failed;
David Aschere2b4b322004-02-18 05:59:53 +00002551 Tcl_Interp *interp = Tkapp_Interp(self);
Neal Norwitz44dbae82004-02-19 02:44:22 +00002552 Tk_Window main_window;
David Aschere2b4b322004-02-18 05:59:53 +00002553 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002554 int err;
Neal Norwitz44dbae82004-02-19 02:44:22 +00002555 main_window = Tk_MainWindow(interp);
David Aschere2b4b322004-02-18 05:59:53 +00002556
Thomas Wouters477c8d52006-05-27 19:21:47 +00002557 /* In all current versions of Tk (including 8.4.13), Tk_Init
2558 deadlocks on the second call when the first call failed.
2559 To avoid the deadlock, we just refuse the second call through
2560 a static variable. */
2561 if (has_failed) {
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002562 PyErr_SetString(Tkinter_TclError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002563 "Calling Tk_Init again after a previous call failed might deadlock");
2564 return NULL;
2565 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002566
David Aschere2b4b322004-02-18 05:59:53 +00002567 /* We want to guard against calling Tk_Init() multiple times */
2568 CHECK_TCL_APPARTMENT;
2569 ENTER_TCL
2570 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2571 ENTER_OVERLAP
2572 if (err == TCL_ERROR) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002573 /* This sets an exception, but we cannot return right
2574 away because we need to exit the overlap first. */
2575 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002576 } else {
2577 _tk_exists = Tkapp_Result(self);
2578 }
2579 LEAVE_OVERLAP_TCL
2580 if (err == TCL_ERROR) {
2581 return NULL;
2582 }
2583 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2584 if (Tk_Init(interp) == TCL_ERROR) {
2585 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
Thomas Wouters477c8d52006-05-27 19:21:47 +00002586 has_failed = 1;
David Aschere2b4b322004-02-18 05:59:53 +00002587 return NULL;
2588 }
2589 }
2590 Py_INCREF(Py_None);
2591 return Py_None;
2592}
Barry Warsawfa701a81997-01-16 00:15:11 +00002593
Martin v. Löwisffad6332002-11-26 09:28:05 +00002594static PyObject *
2595Tkapp_WantObjects(PyObject *self, PyObject *args)
2596{
2597
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002598 int wantobjects = -1;
2599 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002600 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002601 if (wantobjects == -1)
2602 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002603 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002604
2605 Py_INCREF(Py_None);
2606 return Py_None;
2607}
2608
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002609static PyObject *
2610Tkapp_WillDispatch(PyObject *self, PyObject *args)
2611{
2612
2613 ((TkappObject*)self)->dispatching = 1;
2614
2615 Py_INCREF(Py_None);
2616 return Py_None;
2617}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002618
Barry Warsawfa701a81997-01-16 00:15:11 +00002619
Guido van Rossum18468821994-06-20 07:49:28 +00002620/**** Tkapp Method List ****/
2621
2622static PyMethodDef Tkapp_methods[] =
2623{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002624 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002625 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002626 {"call", Tkapp_Call, METH_VARARGS},
2627 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002628 {"eval", Tkapp_Eval, METH_VARARGS},
2629 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2630 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2631 {"record", Tkapp_Record, METH_VARARGS},
2632 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2633 {"setvar", Tkapp_SetVar, METH_VARARGS},
2634 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2635 {"getvar", Tkapp_GetVar, METH_VARARGS},
2636 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2637 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2638 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2639 {"getint", Tkapp_GetInt, METH_VARARGS},
2640 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2641 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2642 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2643 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2644 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2645 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2646 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2647 {"split", Tkapp_Split, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002648 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002649 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2650 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002651#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002652 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2653 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002654#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002655 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2656 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2657 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2658 {"quit", Tkapp_Quit, METH_VARARGS},
2659 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002660 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002661 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002662};
2663
Barry Warsawfa701a81997-01-16 00:15:11 +00002664
2665
Guido van Rossum18468821994-06-20 07:49:28 +00002666/**** Tkapp Type Methods ****/
2667
2668static void
Fred Drake509d79a2000-07-08 04:04:38 +00002669Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002670{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002671 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002672 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002673 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002674 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002675 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002676 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002677}
2678
Guido van Rossum18468821994-06-20 07:49:28 +00002679static PyTypeObject Tkapp_Type =
2680{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002681 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002682 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002683 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002684 0, /*tp_itemsize */
2685 Tkapp_Dealloc, /*tp_dealloc */
2686 0, /*tp_print */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002687 0, /*tp_getattr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002688 0, /*tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002689 0, /*tp_reserved */
Barry Warsawfa701a81997-01-16 00:15:11 +00002690 0, /*tp_repr */
2691 0, /*tp_as_number */
2692 0, /*tp_as_sequence */
2693 0, /*tp_as_mapping */
2694 0, /*tp_hash */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002695 0, /*tp_call*/
2696 0, /*tp_str*/
2697 0, /*tp_getattro*/
2698 0, /*tp_setattro*/
2699 0, /*tp_as_buffer*/
2700 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2701 0, /*tp_doc*/
2702 0, /*tp_traverse*/
2703 0, /*tp_clear*/
2704 0, /*tp_richcompare*/
2705 0, /*tp_weaklistoffset*/
2706 0, /*tp_iter*/
2707 0, /*tp_iternext*/
2708 Tkapp_methods, /*tp_methods*/
Guido van Rossum18468821994-06-20 07:49:28 +00002709};
2710
Barry Warsawfa701a81997-01-16 00:15:11 +00002711
2712
Guido van Rossum18468821994-06-20 07:49:28 +00002713/**** Tkinter Module ****/
2714
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002715typedef struct {
2716 PyObject* tuple;
2717 int size; /* current size */
2718 int maxsize; /* allocated size */
2719} FlattenContext;
2720
2721static int
2722_bump(FlattenContext* context, int size)
2723{
Guido van Rossum2834b972000-10-06 16:58:26 +00002724 /* expand tuple to hold (at least) size new items.
2725 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002726
2727 int maxsize = context->maxsize * 2;
2728
2729 if (maxsize < context->size + size)
2730 maxsize = context->size + size;
2731
2732 context->maxsize = maxsize;
2733
Tim Peters4324aa32001-05-28 22:30:08 +00002734 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002735}
2736
2737static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002738_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002739{
2740 /* add tuple or list to argument tuple (recursively) */
2741
2742 int i, size;
2743
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002744 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002745 PyErr_SetString(PyExc_ValueError,
2746 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002747 return 0;
2748 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002749 size = PyList_GET_SIZE(item);
2750 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002751 if (context->size + size > context->maxsize &&
2752 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002753 return 0;
2754 /* copy items to output tuple */
2755 for (i = 0; i < size; i++) {
2756 PyObject *o = PyList_GET_ITEM(item, i);
2757 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002758 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002759 return 0;
2760 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002761 if (context->size + 1 > context->maxsize &&
2762 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002763 return 0;
2764 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002765 PyTuple_SET_ITEM(context->tuple,
2766 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002767 }
2768 }
2769 } else if (PyTuple_Check(item)) {
2770 /* same, for tuples */
2771 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002772 if (context->size + size > context->maxsize &&
2773 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002774 return 0;
2775 for (i = 0; i < size; i++) {
2776 PyObject *o = PyTuple_GET_ITEM(item, i);
2777 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002778 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002779 return 0;
2780 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002781 if (context->size + 1 > context->maxsize &&
2782 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002783 return 0;
2784 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002785 PyTuple_SET_ITEM(context->tuple,
2786 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002787 }
2788 }
2789 } else {
2790 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2791 return 0;
2792 }
2793 return 1;
2794}
2795
2796static PyObject *
2797Tkinter_Flatten(PyObject* self, PyObject* args)
2798{
2799 FlattenContext context;
2800 PyObject* item;
2801
2802 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2803 return NULL;
2804
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002805 context.maxsize = PySequence_Size(item);
Benjamin Petersonc4bbc8d2009-01-30 03:39:35 +00002806 if (context.maxsize < 0)
2807 return NULL;
2808 if (context.maxsize == 0)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002809 return PyTuple_New(0);
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002810
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002811 context.tuple = PyTuple_New(context.maxsize);
2812 if (!context.tuple)
2813 return NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002814
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002815 context.size = 0;
2816
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002817 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002818 return NULL;
2819
Tim Peters4324aa32001-05-28 22:30:08 +00002820 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002821 return NULL;
2822
2823 return context.tuple;
2824}
2825
Guido van Rossum18468821994-06-20 07:49:28 +00002826static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002827Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002828{
Barry Warsawfa701a81997-01-16 00:15:11 +00002829 char *screenName = NULL;
Martin v. Löwisb9279bc2008-04-05 19:47:23 +00002830 char *baseName = NULL; /* XXX this is not used anymore;
2831 try getting rid of it. */
Barry Warsawfa701a81997-01-16 00:15:11 +00002832 char *className = NULL;
2833 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002834 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002835 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002836 int sync = 0; /* pass -sync to wish */
2837 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002838
Barry Warsawfa701a81997-01-16 00:15:11 +00002839 className = "Tk";
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002840
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002841 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002842 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002843 &interactive, &wantobjects, &wantTk,
2844 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00002845 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002846
Martin v. Löwisb9279bc2008-04-05 19:47:23 +00002847 return (PyObject *) Tkapp_New(screenName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002848 interactive, wantobjects, wantTk,
2849 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002850}
2851
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002852static PyObject *
2853Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2854{
2855 int new_val;
2856 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2857 return NULL;
2858 if (new_val < 0) {
2859 PyErr_SetString(PyExc_ValueError,
2860 "busywaitinterval must be >= 0");
2861 return NULL;
2862 }
2863 Tkinter_busywaitinterval = new_val;
2864 Py_INCREF(Py_None);
2865 return Py_None;
2866}
2867
2868static char setbusywaitinterval_doc[] =
2869"setbusywaitinterval(n) -> None\n\
2870\n\
2871Set the busy-wait interval in milliseconds between successive\n\
2872calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2873It should be set to a divisor of the maximum time between\n\
2874frames in an animation.";
2875
2876static PyObject *
2877Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2878{
Christian Heimes217cfd12007-12-02 14:31:20 +00002879 return PyLong_FromLong(Tkinter_busywaitinterval);
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002880}
2881
2882static char getbusywaitinterval_doc[] =
2883"getbusywaitinterval() -> int\n\
2884\n\
2885Return the current busy-wait interval between successive\n\
2886calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2887
Guido van Rossum18468821994-06-20 07:49:28 +00002888static PyMethodDef moduleMethods[] =
2889{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002890 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2891 {"create", Tkinter_Create, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002892 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2893 setbusywaitinterval_doc},
2894 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2895 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00002896 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002897};
2898
Guido van Rossum7bf15641998-05-22 18:28:17 +00002899#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002900
2901static int stdin_ready = 0;
2902
Guido van Rossumad4db171998-06-13 13:56:28 +00002903#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002904static void
Fred Drake509d79a2000-07-08 04:04:38 +00002905MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002906{
2907 stdin_ready = 1;
2908}
Guido van Rossumad4db171998-06-13 13:56:28 +00002909#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002910
Martin v. Löwisa9656492003-03-30 08:44:58 +00002911#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002912static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002913#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002914
Guido van Rossum18468821994-06-20 07:49:28 +00002915static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002916EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002917{
Guido van Rossumad4db171998-06-13 13:56:28 +00002918#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002919 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002920#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002921#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002922 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002923#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002924 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002925 errorInCmd = 0;
2926#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002927 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002928 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002929#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002930 while (!errorInCmd && !stdin_ready) {
2931 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002932#ifdef MS_WINDOWS
2933 if (_kbhit()) {
2934 stdin_ready = 1;
2935 break;
2936 }
2937#endif
2938#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002939 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002940 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002941 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002942
Guido van Rossum00d93061998-05-28 23:06:38 +00002943 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002944
2945 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002946 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002947 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002948 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00002949 Py_END_ALLOW_THREADS
2950#else
2951 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002952#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002953
2954 if (result < 0)
2955 break;
2956 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002957#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002958 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002959#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002960 if (errorInCmd) {
2961 errorInCmd = 0;
2962 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2963 excInCmd = valInCmd = trbInCmd = NULL;
2964 PyErr_Print();
2965 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002966#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002967 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002968#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002969 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002970}
Guido van Rossum18468821994-06-20 07:49:28 +00002971
Guido van Rossum00d93061998-05-28 23:06:38 +00002972#endif
2973
Guido van Rossum7bf15641998-05-22 18:28:17 +00002974static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002975EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002976{
Guido van Rossum00d93061998-05-28 23:06:38 +00002977#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002978 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002979#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002980 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002981#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002982 PyOS_InputHook = EventHook;
2983 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002984#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002985}
2986
2987static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002988DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002989{
Guido van Rossum00d93061998-05-28 23:06:38 +00002990#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002991 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2992 PyOS_InputHook = NULL;
2993 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002994#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002995}
2996
Barry Warsawfa701a81997-01-16 00:15:11 +00002997
2998/* all errors will be checked in one fell swoop in init_tkinter() */
2999static void
Fred Drake509d79a2000-07-08 04:04:38 +00003000ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003001{
Christian Heimes217cfd12007-12-02 14:31:20 +00003002 PyObject *v = PyLong_FromLong(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003003 if (v) {
3004 PyDict_SetItemString(d, name, v);
3005 Py_DECREF(v);
3006 }
3007}
3008static void
Fred Drake509d79a2000-07-08 04:04:38 +00003009ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003010{
Martin v. Löwis4040fb82007-08-13 06:01:43 +00003011 PyObject *v = PyUnicode_FromString(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003012 if (v) {
3013 PyDict_SetItemString(d, name, v);
3014 Py_DECREF(v);
3015 }
3016}
3017
3018
Martin v. Löwis1a214512008-06-11 05:26:20 +00003019static struct PyModuleDef _tkintermodule = {
3020 PyModuleDef_HEAD_INIT,
3021 "_tkinter",
3022 NULL,
3023 -1,
3024 moduleMethods,
3025 NULL,
3026 NULL,
3027 NULL,
3028 NULL
3029};
3030
Mark Hammond62b1ab12002-07-23 06:31:15 +00003031PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00003032PyInit__tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003033{
Martin v. Löwis790465f2008-04-05 20:41:37 +00003034 PyObject *m, *d, *uexe, *cexe;
Guido van Rossum18468821994-06-20 07:49:28 +00003035
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00003036 if (PyType_Ready(&Tkapp_Type) < 0)
3037 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00003038
3039#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003040 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003041#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003042
Martin v. Löwis1a214512008-06-11 05:26:20 +00003043 m = PyModule_Create(&_tkintermodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003044 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00003045 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00003046
Barry Warsawfa701a81997-01-16 00:15:11 +00003047 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003048 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003049 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003050
Guido van Rossum35d43371997-08-02 00:09:09 +00003051 ins_long(d, "READABLE", TCL_READABLE);
3052 ins_long(d, "WRITABLE", TCL_WRITABLE);
3053 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3054 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3055 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3056 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3057 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3058 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3059 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003060 ins_string(d, "TK_VERSION", TK_VERSION);
3061 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003062
Guido van Rossum83551bf1997-09-13 00:44:23 +00003063 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003064
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00003065 if (PyType_Ready(&Tktt_Type) < 0)
3066 return NULL;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003067 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3068
Christian Heimes90aa7642007-12-19 02:45:37 +00003069 Py_TYPE(&PyTclObject_Type) = &PyType_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003070 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003071
3072#ifdef TK_AQUA
3073 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3074 * start waking up. Note that Tcl_FindExecutable will do this, this
3075 * code must be above it! The original warning from
3076 * tkMacOSXAppInit.c is copied below.
3077 *
3078 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3079 * Tcl interpreter for now. It probably should work to do this
3080 * in the other order, but for now it doesn't seem to.
3081 *
3082 */
3083 Tk_MacOSXSetupTkNotifier();
3084#endif
3085
3086
Guido van Rossume187b0e2000-03-27 21:46:29 +00003087 /* This helps the dynamic loader; in Unicode aware Tcl versions
3088 it also helps Tcl find its encodings. */
Martin v. Löwis790465f2008-04-05 20:41:37 +00003089 uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1);
3090 if (uexe) {
3091 cexe = PyUnicode_AsEncodedString(uexe,
3092 Py_FileSystemDefaultEncoding,
3093 NULL);
3094 if (cexe)
Christian Heimes72b710a2008-05-26 13:28:38 +00003095 Tcl_FindExecutable(PyBytes_AsString(cexe));
Martin v. Löwis790465f2008-04-05 20:41:37 +00003096 Py_XDECREF(cexe);
3097 Py_DECREF(uexe);
3098 }
Guido van Rossume187b0e2000-03-27 21:46:29 +00003099
Martin v. Löwis1a214512008-06-11 05:26:20 +00003100 if (PyErr_Occurred()) {
3101 Py_DECREF(m);
3102 return NULL;
3103 }
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003104
Guido van Rossum43ff8681998-07-14 18:02:13 +00003105#if 0
3106 /* This was not a good idea; through <Destroy> bindings,
3107 Tcl_Finalize() may invoke Python code but at that point the
3108 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003109 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003110#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +00003111 return m;
Guido van Rossum18468821994-06-20 07:49:28 +00003112}