blob: 93e7edc546c0d0b78eeea8b90d243cac3b14976b [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
Guido van Rossum845547d1996-06-26 18:26:04 +00003
4 All Rights Reserved
5
Guido van Rossum845547d1996-06-26 18:26:04 +00006******************************************************************/
7
8/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +00009
Guido van Rossum7ffa7611996-08-13 21:10:16 +000010/* TCL/TK VERSION INFO:
11
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000012 Only Tcl/Tk 8.2 and later are supported. Older versions are not
13 supported. (Use Python 2.2 if you cannot upgrade your Tcl/Tk
Guido van Rossuma80649b2000-03-28 20:07:05 +000014 libraries.)
15*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000016
Guido van Rossuma80649b2000-03-28 20:07:05 +000017/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000018
Guido van Rossum212643f1998-04-29 16:22:14 +000019 - Register a new Tcl type, "Python callable", which can be called more
20 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
21
Guido van Rossum7ffa7611996-08-13 21:10:16 +000022*/
23
Guido van Rossum35d43371997-08-02 00:09:09 +000024
Guido van Rossum9722ad81995-09-22 23:49:28 +000025#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000026#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000027
Guido van Rossum00d93061998-05-28 23:06:38 +000028#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000029#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000030#endif
31
Guido van Rossum2a5119b1998-05-29 01:28:40 +000032#ifdef MS_WINDOWS
33#include <windows.h>
34#endif
35
Martin v. Löwis39195712003-01-04 00:33:13 +000036/* Allow using this code in Python 2.[12] */
37#ifndef PyDoc_STRVAR
Martin v. Löwiscd9a8b62003-01-21 21:52:57 +000038#define PyDoc_STRVAR(name,str) static char name[] = str
Martin v. Löwis39195712003-01-04 00:33:13 +000039#endif
40
41#ifndef PyMODINIT_FUNC
Martin v. Löwis3a57d9d2003-01-04 08:54:59 +000042#define PyMODINIT_FUNC void
Martin v. Löwis39195712003-01-04 00:33:13 +000043#endif
44
Martin v. Löwis52ae6f62003-03-30 08:26:04 +000045#ifndef PyBool_Check
46#define PyBool_Check(o) 0
47#define PyBool_FromLong PyInt_FromLong
48#endif
49
Martin v. Löwis71e25a02002-10-01 18:08:06 +000050/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
51 making _tkinter correct for this API means to break earlier
52 versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
53 earlier versions. Once Tcl releases before 8.4 don't need to be supported
54 anymore, this should go. */
55#define USE_COMPAT_CONST
56
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000057/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
58 it always; if Tcl is not threaded, the thread functions in
59 Tcl are empty. */
60#define TCL_THREADS
61
Jack Jansencb852442001-12-09 23:15:56 +000062#ifdef TK_FRAMEWORK
63#include <Tcl/tcl.h>
64#include <Tk/tk.h>
65#else
Guido van Rossum18468821994-06-20 07:49:28 +000066#include <tcl.h>
67#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000068#endif
Guido van Rossum18468821994-06-20 07:49:28 +000069
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
Martin v. Löwis6f29ff32003-04-16 20:34:55 +000086 either UTF-16 or UCS-4.
87 Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for
88 Tcl_Unichar. This is also ok as long as Python uses UCS-4,
89 as well.
90*/
91#if TCL_UTF_MAX != 3 && !(defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==6)
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000092#error "unsupported Tcl configuration"
93#endif
94
Jack Janseneddc1442003-11-20 01:44:59 +000095#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
Guido van Rossum0d2390c1997-08-14 19:57:07 +000096#define HAVE_CREATEFILEHANDLER
97#endif
98
Guido van Rossum00d93061998-05-28 23:06:38 +000099#ifdef HAVE_CREATEFILEHANDLER
100
Neal Norwitzd948a432006-01-08 01:08:55 +0000101/* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere
102 with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */
103#ifndef TCL_UNIX_FD
104# ifdef TCL_WIN_SOCKET
105# define TCL_UNIX_FD (! TCL_WIN_SOCKET)
106# else
107# define TCL_UNIX_FD 1
108# endif
109#endif
110
Guido van Rossum00d93061998-05-28 23:06:38 +0000111/* Tcl_CreateFileHandler() changed several times; these macros deal with the
112 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
113 Unix, only because Jack added it back); when available on Windows, it only
114 applies to sockets. */
115
Guido van Rossum7bf15641998-05-22 18:28:17 +0000116#ifdef MS_WINDOWS
117#define FHANDLETYPE TCL_WIN_SOCKET
118#else
119#define FHANDLETYPE TCL_UNIX_FD
120#endif
121
Guido van Rossum00d93061998-05-28 23:06:38 +0000122/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
123 which uses this to handle Tcl events while the user is typing commands. */
124
125#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000126#define WAIT_FOR_STDIN
127#endif
128
Guido van Rossum00d93061998-05-28 23:06:38 +0000129#endif /* HAVE_CREATEFILEHANDLER */
130
Guido van Rossumad4db171998-06-13 13:56:28 +0000131#ifdef MS_WINDOWS
132#include <conio.h>
133#define WAIT_FOR_STDIN
134#endif
135
Guido van Rossum00d93061998-05-28 23:06:38 +0000136#ifdef WITH_THREAD
137
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000138/* The threading situation is complicated. Tcl is not thread-safe, except
139 when configured with --enable-threads.
Guido van Rossum00d93061998-05-28 23:06:38 +0000140 So we need to use a lock around all uses of Tcl. Previously, the Python
141 interpreter lock was used for this. However, this causes problems when
142 other Python threads need to run while Tcl is blocked waiting for events.
143
144 To solve this problem, a separate lock for Tcl is introduced. Holding it
145 is incompatible with holding Python's interpreter lock. The following four
146 macros manipulate both locks together.
147
148 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
149 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
150 that could call an event handler, or otherwise affect the state of a Tcl
151 interpreter. These assume that the surrounding code has the Python
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000152 interpreter lock; inside the brackets, the Python interpreter lock has been
Guido van Rossum00d93061998-05-28 23:06:38 +0000153 released and the lock for Tcl has been acquired.
154
Guido van Rossum5e977831998-06-15 14:03:52 +0000155 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
156 (For example, when transferring data from the Tcl interpreter result to a
157 Python string object.) This can be done by using different macros to close
158 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
159 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
160 releases the Tcl lock.
161
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000162 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000163 handlers when the handler needs to use Python. Such event handlers are
164 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000165 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000166 the Python interpreter lock, restoring the appropriate thread state, and
167 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
168 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000169 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000170
171 These locks expand to several statements and brackets; they should not be
172 used in branches of if statements and the like.
173
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000174 If Tcl is threaded, this approach won't work anymore. The Tcl interpreter is
175 only valid in the thread that created it, and all Tk activity must happen in this
176 thread, also. That means that the mainloop must be invoked in the thread that
177 created the interpreter. Invoking commands from other threads is possible;
178 _tkinter will queue an event for the interpreter thread, which will then
179 execute the command and pass back the result. If the main thread is not in the
180 mainloop, and invoking commands causes an exception; if the main loop is running
181 but not processing events, the command invocation will block.
182
183 In addition, for a threaded Tcl, a single global tcl_tstate won't be sufficient
184 anymore, since multiple Tcl interpreters may simultaneously dispatch in different
185 threads. So we use the Tcl TLS API.
186
Guido van Rossum00d93061998-05-28 23:06:38 +0000187*/
188
Guido van Rossum65d5b571998-12-21 19:32:43 +0000189static PyThread_type_lock tcl_lock = 0;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000190
191#ifdef TCL_THREADS
192static Tcl_ThreadDataKey state_key;
193typedef PyThreadState *ThreadSpecificData;
194#define tcl_tstate (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*)))
195#else
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000196static PyThreadState *tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000197#endif
Guido van Rossum00d93061998-05-28 23:06:38 +0000198
199#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000200 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000201 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000202
203#define LEAVE_TCL \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000204 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000205
Guido van Rossum62320c91998-06-15 04:36:09 +0000206#define ENTER_OVERLAP \
207 Py_END_ALLOW_THREADS
208
209#define LEAVE_OVERLAP_TCL \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000210 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000211
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000212#define ENTER_PYTHON \
213 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000214 if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000215
216#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000217 { PyThreadState *tstate = PyEval_SaveThread(); \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000218 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
219
220#define CHECK_TCL_APPARTMENT \
221 if (((TkappObject *)self)->threaded && \
222 ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
223 PyErr_SetString(PyExc_RuntimeError, "Calling Tcl from different appartment"); \
224 return 0; \
225 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000226
227#else
228
229#define ENTER_TCL
230#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000231#define ENTER_OVERLAP
232#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000233#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000234#define LEAVE_PYTHON
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000235#define CHECK_TCL_APPARTMENT
Guido van Rossum00d93061998-05-28 23:06:38 +0000236
237#endif
238
Guido van Rossum97867b21996-08-08 19:09:53 +0000239#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000240#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000241#endif
242
Guido van Rossum18468821994-06-20 07:49:28 +0000243/**** Tkapp Object Declaration ****/
244
Jeremy Hylton938ace62002-07-17 16:30:39 +0000245static PyTypeObject Tkapp_Type;
Guido van Rossum18468821994-06-20 07:49:28 +0000246
Guido van Rossum00d93061998-05-28 23:06:38 +0000247typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000248 PyObject_HEAD
249 Tcl_Interp *interp;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000250 int wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000251 int threaded; /* True if tcl_platform[threaded] */
252 Tcl_ThreadId thread_id;
253 int dispatching;
254 /* We cannot include tclInt.h, as this is internal.
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000255 So we cache interesting types here. */
256 Tcl_ObjType *BooleanType;
257 Tcl_ObjType *ByteArrayType;
258 Tcl_ObjType *DoubleType;
259 Tcl_ObjType *IntType;
260 Tcl_ObjType *ListType;
261 Tcl_ObjType *ProcBodyType;
262 Tcl_ObjType *StringType;
Guido van Rossum00d93061998-05-28 23:06:38 +0000263} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000264
Christian Heimese93237d2007-12-19 02:37:44 +0000265#define Tkapp_Check(v) (Py_TYPE(v) == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000266#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000267#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000268
Guido van Rossum35d43371997-08-02 00:09:09 +0000269#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Christian Heimese93237d2007-12-19 02:37:44 +0000270(void *) v, Py_REFCNT(v)))
Guido van Rossum18468821994-06-20 07:49:28 +0000271
Barry Warsawfa701a81997-01-16 00:15:11 +0000272
273
Guido van Rossum18468821994-06-20 07:49:28 +0000274/**** Error Handling ****/
275
276static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000277static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000278static int errorInCmd = 0;
279static PyObject *excInCmd;
280static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000282
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{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000338 if (PyString_Check(value))
339 return PyString_AsString(value);
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000340#ifdef Py_USING_UNICODE
Guido van Rossum2834b972000-10-06 16:58:26 +0000341 else if (PyUnicode_Check(value)) {
342 PyObject *v = PyUnicode_AsUTF8String(value);
343 if (v == NULL)
344 return NULL;
345 if (PyList_Append(tmp, v) != 0) {
346 Py_DECREF(v);
347 return NULL;
348 }
349 Py_DECREF(v);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000350 return PyString_AsString(v);
Guido van Rossum2834b972000-10-06 16:58:26 +0000351 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000352#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000353 else {
354 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000355 if (v == NULL)
356 return NULL;
357 if (PyList_Append(tmp, v) != 0) {
358 Py_DECREF(v);
359 return NULL;
360 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000361 Py_DECREF(v);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000362 return PyString_AsString(v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000363 }
Guido van Rossum18468821994-06-20 07:49:28 +0000364}
365
Barry Warsawfa701a81997-01-16 00:15:11 +0000366
367
Guido van Rossum18468821994-06-20 07:49:28 +0000368#define ARGSZ 64
369
370static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000371Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000372{
Barry Warsawfa701a81997-01-16 00:15:11 +0000373 PyObject *tmp = NULL;
374 char *argvStore[ARGSZ];
375 char **argv = NULL;
376 int fvStore[ARGSZ];
377 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000378 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000379 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000380
Barry Warsawfa701a81997-01-16 00:15:11 +0000381 if (!(tmp = PyList_New(0)))
382 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 argv = argvStore;
385 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000386
Barry Warsawfa701a81997-01-16 00:15:11 +0000387 if (args == NULL)
388 argc = 0;
389
390 else if (!PyTuple_Check(args)) {
391 argc = 1;
392 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000393 if (!(argv[0] = AsString(args, tmp)))
394 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000395 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000396 else {
397 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000398
Barry Warsawfa701a81997-01-16 00:15:11 +0000399 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000400 argv = (char **)ckalloc(argc * sizeof(char *));
401 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000402 if (argv == NULL || fv == NULL) {
403 PyErr_NoMemory();
404 goto finally;
405 }
406 }
407
408 for (i = 0; i < argc; i++) {
409 PyObject *v = PyTuple_GetItem(args, i);
410 if (PyTuple_Check(v)) {
411 fv[i] = 1;
412 if (!(argv[i] = Merge(v)))
413 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000414 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000415 }
416 else if (v == Py_None) {
417 argc = i;
418 break;
419 }
420 else {
421 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000422 if (!(argv[i] = AsString(v, tmp)))
423 goto finally;
424 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000425 }
426 }
Guido van Rossum18468821994-06-20 07:49:28 +0000427 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000429 if (res == NULL)
430 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000431
Barry Warsawfa701a81997-01-16 00:15:11 +0000432 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000433 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000434 if (fv[i]) {
435 ckfree(argv[i]);
436 }
437 if (argv != argvStore)
438 ckfree(FREECAST argv);
439 if (fv != fvStore)
440 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000441
Barry Warsawfa701a81997-01-16 00:15:11 +0000442 Py_DECREF(tmp);
443 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000444}
445
Barry Warsawfa701a81997-01-16 00:15:11 +0000446
447
Guido van Rossum18468821994-06-20 07:49:28 +0000448static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000449Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000450{
Barry Warsawfa701a81997-01-16 00:15:11 +0000451 int argc;
452 char **argv;
453 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000454
Barry Warsawfa701a81997-01-16 00:15:11 +0000455 if (list == NULL) {
456 Py_INCREF(Py_None);
457 return Py_None;
458 }
Guido van Rossum18468821994-06-20 07:49:28 +0000459
Guido van Rossum00d93061998-05-28 23:06:38 +0000460 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000461 /* Not a list.
462 * Could be a quoted string containing funnies, e.g. {"}.
463 * Return the string itself.
464 */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000465 return PyString_FromString(list);
Barry Warsawfa701a81997-01-16 00:15:11 +0000466 }
Guido van Rossum18468821994-06-20 07:49:28 +0000467
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 if (argc == 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000469 v = PyString_FromString("");
Barry Warsawfa701a81997-01-16 00:15:11 +0000470 else if (argc == 1)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000471 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000472 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000473 int i;
474 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000475
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000477 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000478 Py_DECREF(v);
479 v = NULL;
480 break;
481 }
482 PyTuple_SetItem(v, i, w);
483 }
484 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000485 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000486 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000487}
488
Martin v. Löwisffad6332002-11-26 09:28:05 +0000489/* In some cases, Tcl will still return strings that are supposed to be
490 lists. SplitObj walks through a nested tuple, finding string objects that
491 need to be split. */
492
Martin v. Löwis111c1802008-06-13 07:47:47 +0000493static PyObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000494SplitObj(PyObject *arg)
495{
496 if (PyTuple_Check(arg)) {
497 int i, size;
498 PyObject *elem, *newelem, *result;
499
500 size = PyTuple_Size(arg);
501 result = NULL;
502 /* Recursively invoke SplitObj for all tuple items.
503 If this does not return a new object, no action is
504 needed. */
505 for(i = 0; i < size; i++) {
506 elem = PyTuple_GetItem(arg, i);
507 newelem = SplitObj(elem);
508 if (!newelem) {
509 Py_XDECREF(result);
510 return NULL;
511 }
512 if (!result) {
513 int k;
514 if (newelem == elem) {
515 Py_DECREF(newelem);
516 continue;
517 }
518 result = PyTuple_New(size);
519 if (!result)
520 return NULL;
521 for(k = 0; k < i; k++) {
522 elem = PyTuple_GetItem(arg, k);
523 Py_INCREF(elem);
524 PyTuple_SetItem(result, k, elem);
525 }
526 }
527 PyTuple_SetItem(result, i, newelem);
528 }
529 if (result)
530 return result;
531 /* Fall through, returning arg. */
532 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000533 else if (PyString_Check(arg)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000534 int argc;
535 char **argv;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000536 char *list = PyString_AsString(arg);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000537
538 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
539 Py_INCREF(arg);
540 return arg;
541 }
542 Tcl_Free(FREECAST argv);
543 if (argc > 1)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000544 return Split(PyString_AsString(arg));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000545 /* Fall through, returning arg. */
546 }
547 Py_INCREF(arg);
548 return arg;
549}
Barry Warsawfa701a81997-01-16 00:15:11 +0000550
551
Guido van Rossum18468821994-06-20 07:49:28 +0000552/**** Tkapp Object ****/
553
554#ifndef WITH_APPINIT
555int
Fred Drake509d79a2000-07-08 04:04:38 +0000556Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000557{
Barry Warsawfa701a81997-01-16 00:15:11 +0000558 Tk_Window main;
David Aschere2b4b322004-02-18 05:59:53 +0000559 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000560
Barry Warsawfa701a81997-01-16 00:15:11 +0000561 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000562 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000563 return TCL_ERROR;
564 }
David Aschere2b4b322004-02-18 05:59:53 +0000565 _tkinter_skip_tk_init = Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
566 if (_tkinter_skip_tk_init == NULL || strcmp(_tkinter_skip_tk_init, "1") != 0) {
567 main = Tk_MainWindow(interp);
568 if (Tk_Init(interp) == TCL_ERROR) {
569 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
570 return TCL_ERROR;
571 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000572 }
573 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000574}
575#endif /* !WITH_APPINIT */
576
Guido van Rossum18468821994-06-20 07:49:28 +0000577
Barry Warsawfa701a81997-01-16 00:15:11 +0000578
579
580/* Initialize the Tk application; see the `main' function in
581 * `tkMain.c'.
582 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000583
Thomas Wouters58d05102000-07-24 14:43:35 +0000584static void EnableEventHook(void); /* Forward */
585static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000586
Barry Warsawfa701a81997-01-16 00:15:11 +0000587static TkappObject *
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000588Tkapp_New(char *screenName, char *baseName, char *className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000589 int interactive, int wantobjects, int wantTk, int sync, char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000590{
591 TkappObject *v;
592 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000593
Guido van Rossumb18618d2000-05-03 23:44:39 +0000594 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000595 if (v == NULL)
596 return NULL;
597
598 v->interp = Tcl_CreateInterp();
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000599 v->wantobjects = wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000600 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
601 TCL_GLOBAL_ONLY) != NULL;
602 v->thread_id = Tcl_GetCurrentThread();
603 v->dispatching = 0;
604
605#ifndef TCL_THREADS
606 if (v->threaded) {
607 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
608 Py_DECREF(v);
609 return 0;
610 }
611#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000612#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000613 if (v->threaded && tcl_lock) {
614 /* If Tcl is threaded, we don't need the lock. */
615 PyThread_free_lock(tcl_lock);
616 tcl_lock = NULL;
617 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000618#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000619
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000620 v->BooleanType = Tcl_GetObjType("boolean");
621 v->ByteArrayType = Tcl_GetObjType("bytearray");
622 v->DoubleType = Tcl_GetObjType("double");
623 v->IntType = Tcl_GetObjType("int");
624 v->ListType = Tcl_GetObjType("list");
625 v->ProcBodyType = Tcl_GetObjType("procbody");
626 v->StringType = Tcl_GetObjType("string");
627
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000628 /* Delete the 'exit' command, which can screw things up */
629 Tcl_DeleteCommand(v->interp, "exit");
630
Barry Warsawfa701a81997-01-16 00:15:11 +0000631 if (screenName != NULL)
632 Tcl_SetVar2(v->interp, "env", "DISPLAY",
633 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000634
Barry Warsawfa701a81997-01-16 00:15:11 +0000635 if (interactive)
636 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
637 else
638 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000639
Barry Warsawfa701a81997-01-16 00:15:11 +0000640 /* This is used to get the application class for Tk 4.1 and up */
641 argv0 = (char*)ckalloc(strlen(className) + 1);
642 if (!argv0) {
643 PyErr_NoMemory();
644 Py_DECREF(v);
645 return NULL;
646 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000647
Barry Warsawfa701a81997-01-16 00:15:11 +0000648 strcpy(argv0, className);
Neal Norwitz9dbc7dd2005-12-19 06:08:59 +0000649 if (isupper(Py_CHARMASK(argv0[0])))
Neal Norwitz65c05b22006-04-10 02:17:47 +0000650 argv0[0] = tolower(Py_CHARMASK(argv0[0]));
Barry Warsawfa701a81997-01-16 00:15:11 +0000651 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
652 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000653
David Aschere2b4b322004-02-18 05:59:53 +0000654 if (! wantTk) {
655 Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
656 }
657
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000658 /* some initial arguments need to be in argv */
659 if (sync || use) {
Tim Peters51fa3b72004-08-04 02:16:48 +0000660 char *args;
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000661 int len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000662
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000663 if (sync)
664 len += sizeof "-sync";
665 if (use)
666 len += strlen(use) + sizeof "-use ";
667
Tim Peters51fa3b72004-08-04 02:16:48 +0000668 args = (char*)ckalloc(len);
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000669 if (!args) {
670 PyErr_NoMemory();
671 Py_DECREF(v);
672 return NULL;
673 }
674
675 args[0] = '\0';
676 if (sync)
677 strcat(args, "-sync");
678 if (use) {
679 if (sync)
680 strcat(args, " ");
681 strcat(args, "-use ");
682 strcat(args, use);
683 }
684
685 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
686 ckfree(args);
687 }
688
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000689 if (Tcl_AppInit(v->interp) != TCL_OK) {
690 PyObject *result = Tkinter_Error((PyObject *)v);
691 Py_DECREF((PyObject *)v);
692 return (TkappObject *)result;
693 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000694
Guido van Rossum7bf15641998-05-22 18:28:17 +0000695 EnableEventHook();
696
Barry Warsawfa701a81997-01-16 00:15:11 +0000697 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000698}
699
Barry Warsawfa701a81997-01-16 00:15:11 +0000700
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000701static void
702Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
703 Tcl_Condition *cond, Tcl_Mutex *mutex)
704{
705 Py_BEGIN_ALLOW_THREADS;
706 Tcl_MutexLock(mutex);
707 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
708 Tcl_ThreadAlert(self->thread_id);
709 Tcl_ConditionWait(cond, mutex, NULL);
710 Tcl_MutexUnlock(mutex);
711 Py_END_ALLOW_THREADS
712}
713
Barry Warsawfa701a81997-01-16 00:15:11 +0000714
Guido van Rossum18468821994-06-20 07:49:28 +0000715/** Tcl Eval **/
716
Martin v. Löwisffad6332002-11-26 09:28:05 +0000717typedef struct {
718 PyObject_HEAD
719 Tcl_Obj *value;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000720 PyObject *string; /* This cannot cause cycles. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000721} PyTclObject;
722
723staticforward PyTypeObject PyTclObject_Type;
724#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
725
726static PyObject *
727newPyTclObject(Tcl_Obj *arg)
728{
729 PyTclObject *self;
730 self = PyObject_New(PyTclObject, &PyTclObject_Type);
731 if (self == NULL)
732 return NULL;
733 Tcl_IncrRefCount(arg);
734 self->value = arg;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000735 self->string = NULL;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000736 return (PyObject*)self;
737}
738
739static void
740PyTclObject_dealloc(PyTclObject *self)
741{
742 Tcl_DecrRefCount(self->value);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000743 Py_XDECREF(self->string);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000744 PyObject_Del(self);
745}
746
747static PyObject *
748PyTclObject_str(PyTclObject *self)
749{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000750 if (self->string && PyString_Check(self->string)) {
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000751 Py_INCREF(self->string);
752 return self->string;
753 }
754 /* XXX Could cache value if it is an ASCII string. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000755 return PyString_FromString(Tcl_GetString(self->value));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000756}
757
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000758static char*
759PyTclObject_TclString(PyObject *self)
760{
761 return Tcl_GetString(((PyTclObject*)self)->value);
762}
763
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000764/* Like _str, but create Unicode if necessary. */
Martin v. Löwis39195712003-01-04 00:33:13 +0000765PyDoc_STRVAR(PyTclObject_string__doc__,
766"the string representation of this object, either as string or Unicode");
767
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000768static PyObject *
769PyTclObject_string(PyTclObject *self, void *ignored)
770{
771 char *s;
772 int i, len;
773 if (!self->string) {
774 s = Tcl_GetStringFromObj(self->value, &len);
775 for (i = 0; i < len; i++)
776 if (s[i] & 0x80)
777 break;
778#ifdef Py_USING_UNICODE
779 if (i == len)
780 /* It is an ASCII string. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000781 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000782 else {
783 self->string = PyUnicode_DecodeUTF8(s, len, "strict");
784 if (!self->string) {
785 PyErr_Clear();
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000786 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000787 }
788 }
789#else
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000790 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000791#endif
792 if (!self->string)
793 return NULL;
794 }
795 Py_INCREF(self->string);
796 return self->string;
797}
798
799#ifdef Py_USING_UNICODE
Martin v. Löwis39195712003-01-04 00:33:13 +0000800PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode");
801
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000802static PyObject *
803PyTclObject_unicode(PyTclObject *self, void *ignored)
804{
805 char *s;
806 int len;
807 if (self->string && PyUnicode_Check(self->string)) {
808 Py_INCREF(self->string);
809 return self->string;
810 }
811 /* XXX Could chache result if it is non-ASCII. */
812 s = Tcl_GetStringFromObj(self->value, &len);
813 return PyUnicode_DecodeUTF8(s, len, "strict");
814}
815#endif
816
Martin v. Löwisffad6332002-11-26 09:28:05 +0000817static PyObject *
818PyTclObject_repr(PyTclObject *self)
819{
820 char buf[50];
Martin v. Löwisfba73692004-11-13 11:13:35 +0000821 PyOS_snprintf(buf, 50, "<%s object at %p>",
822 self->value->typePtr->name, self->value);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000823 return PyString_FromString(buf);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000824}
825
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000826static int
827PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
828{
829 int res;
830 res = strcmp(Tcl_GetString(self->value),
831 Tcl_GetString(other->value));
832 if (res < 0) return -1;
833 if (res > 0) return 1;
834 return 0;
835}
836
Martin v. Löwis39195712003-01-04 00:33:13 +0000837PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
838
Martin v. Löwisffad6332002-11-26 09:28:05 +0000839static PyObject*
840get_typename(PyTclObject* obj, void* ignored)
841{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000842 return PyString_FromString(obj->value->typePtr->name);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000843}
844
Martin v. Löwis39195712003-01-04 00:33:13 +0000845
Martin v. Löwisffad6332002-11-26 09:28:05 +0000846static PyGetSetDef PyTclObject_getsetlist[] = {
Martin v. Löwis39195712003-01-04 00:33:13 +0000847 {"typename", (getter)get_typename, NULL, get_typename__doc__},
848 {"string", (getter)PyTclObject_string, NULL,
849 PyTclObject_string__doc__},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000850 {0},
851};
852
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000853static PyMethodDef PyTclObject_methods[] = {
Martin v. Löwise2713be2005-03-08 15:03:08 +0000854#ifdef Py_USING_UNICODE
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000855 {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS,
Martin v. Löwis39195712003-01-04 00:33:13 +0000856 PyTclObject_unicode__doc__},
Martin v. Löwise2713be2005-03-08 15:03:08 +0000857#endif
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000858 {0}
859};
860
Martin v. Löwisffad6332002-11-26 09:28:05 +0000861statichere PyTypeObject PyTclObject_Type = {
862 PyObject_HEAD_INIT(NULL)
863 0, /*ob_size*/
864 "_tkinter.Tcl_Obj", /*tp_name*/
865 sizeof(PyTclObject), /*tp_basicsize*/
866 0, /*tp_itemsize*/
867 /* methods */
868 (destructor)PyTclObject_dealloc, /*tp_dealloc*/
869 0, /*tp_print*/
870 0, /*tp_getattr*/
871 0, /*tp_setattr*/
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000872 (cmpfunc)PyTclObject_cmp, /*tp_compare*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000873 (reprfunc)PyTclObject_repr, /*tp_repr*/
874 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*/
Jason Tishlerfb8595d2003-01-06 12:41:26 +0000880 PyObject_GenericGetAttr,/*tp_getattro*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000881 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 0, /*tp_richcompare*/
888 0, /*tp_weaklistoffset*/
889 0, /*tp_iter*/
890 0, /*tp_iternext*/
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000891 PyTclObject_methods, /*tp_methods*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000892 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*/
904};
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;
910
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000911 if (PyString_Check(value))
912 return Tcl_NewStringObj(PyString_AS_STRING(value),
913 PyString_GET_SIZE(value));
Martin v. Löwis70c3dda2003-01-22 09:17:38 +0000914 else if (PyBool_Check(value))
915 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000916 else if (PyInt_Check(value))
917 return Tcl_NewLongObj(PyInt_AS_LONG(value));
918 else if (PyFloat_Check(value))
919 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
920 else if (PyTuple_Check(value)) {
921 Tcl_Obj **argv = (Tcl_Obj**)
922 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
923 int i;
924 if(!argv)
925 return 0;
926 for(i=0;i<PyTuple_Size(value);i++)
927 argv[i] = AsObj(PyTuple_GetItem(value,i));
928 result = Tcl_NewListObj(PyTuple_Size(value), argv);
929 ckfree(FREECAST argv);
930 return result;
931 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000932#ifdef Py_USING_UNICODE
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000933 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000934 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
Neal Norwitz047f3c72006-06-12 02:06:42 +0000935 Py_ssize_t size = PyUnicode_GET_SIZE(value);
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000936 /* This #ifdef assumes that Tcl uses UCS-2.
937 See TCL_UTF_MAX test above. */
Martin v. Löwis6f29ff32003-04-16 20:34:55 +0000938#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
Guido van Rossum076d9ee2008-01-03 23:54:04 +0000939 Tcl_UniChar *outbuf = NULL;
Neal Norwitz047f3c72006-06-12 02:06:42 +0000940 Py_ssize_t i;
Guido van Rossum076d9ee2008-01-03 23:54:04 +0000941 size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
942 if (allocsize >= size)
943 outbuf = (Tcl_UniChar*)ckalloc(allocsize);
944 /* Else overflow occurred, and we take the next exit */
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000945 if (!outbuf) {
946 PyErr_NoMemory();
947 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000948 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000949 for (i = 0; i < size; i++) {
950 if (inbuf[i] >= 0x10000) {
951 /* Tcl doesn't do UTF-16, yet. */
952 PyErr_SetString(PyExc_ValueError,
953 "unsupported character");
954 ckfree(FREECAST outbuf);
955 return NULL;
956 }
957 outbuf[i] = inbuf[i];
958 }
959 result = Tcl_NewUnicodeObj(outbuf, size);
960 ckfree(FREECAST outbuf);
961 return result;
962#else
963 return Tcl_NewUnicodeObj(inbuf, size);
964#endif
965
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000966 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000967#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +0000968 else if(PyTclObject_Check(value)) {
969 Tcl_Obj *v = ((PyTclObject*)value)->value;
970 Tcl_IncrRefCount(v);
971 return v;
972 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000973 else {
974 PyObject *v = PyObject_Str(value);
975 if (!v)
976 return 0;
977 result = AsObj(v);
978 Py_DECREF(v);
979 return result;
980 }
981}
982
Martin v. Löwisffad6332002-11-26 09:28:05 +0000983static PyObject*
984FromObj(PyObject* tkapp, Tcl_Obj *value)
985{
986 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000987 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000988
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000989 if (value->typePtr == NULL) {
990 /* If the result contains any bytes with the top bit set,
991 it's UTF-8 and we should decode it to Unicode */
992#ifdef Py_USING_UNICODE
993 int i;
994 char *s = value->bytes;
995 int len = value->length;
996 for (i = 0; i < len; i++) {
997 if (value->bytes[i] & 0x80)
998 break;
999 }
1000
1001 if (i == value->length)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001002 result = PyString_FromStringAndSize(s, len);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001003 else {
1004 /* Convert UTF-8 to Unicode string */
1005 result = PyUnicode_DecodeUTF8(s, len, "strict");
1006 if (result == NULL) {
1007 PyErr_Clear();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001008 result = PyString_FromStringAndSize(s, len);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001009 }
1010 }
1011#else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001012 result = PyString_FromStringAndSize(value->bytes, value->length);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001013#endif
1014 return result;
1015 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001016
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001017 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001018 result = value->internalRep.longValue ? Py_True : Py_False;
1019 Py_INCREF(result);
1020 return result;
1021 }
1022
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001023 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001024 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +00001025 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001026 return PyString_FromStringAndSize(data, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001027 }
1028
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001029 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001030 return PyFloat_FromDouble(value->internalRep.doubleValue);
1031 }
1032
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001033 if (value->typePtr == app->IntType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001034 return PyInt_FromLong(value->internalRep.longValue);
1035 }
1036
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001037 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001038 int size;
1039 int i, status;
1040 PyObject *elem;
1041 Tcl_Obj *tcl_elem;
1042
1043 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
1044 if (status == TCL_ERROR)
1045 return Tkinter_Error(tkapp);
1046 result = PyTuple_New(size);
1047 if (!result)
1048 return NULL;
1049 for (i = 0; i < size; i++) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001050 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
Martin v. Löwisffad6332002-11-26 09:28:05 +00001051 value, i, &tcl_elem);
1052 if (status == TCL_ERROR) {
1053 Py_DECREF(result);
1054 return Tkinter_Error(tkapp);
1055 }
1056 elem = FromObj(tkapp, tcl_elem);
1057 if (!elem) {
1058 Py_DECREF(result);
1059 return NULL;
1060 }
1061 PyTuple_SetItem(result, i, elem);
1062 }
1063 return result;
1064 }
1065
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001066 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001067 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +00001068 }
1069
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001070 if (value->typePtr == app->StringType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001071#ifdef Py_USING_UNICODE
Martin v. Löwis6f29ff32003-04-16 20:34:55 +00001072#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
Martin v. Löwisffad6332002-11-26 09:28:05 +00001073 PyObject *result;
1074 int size;
1075 Tcl_UniChar *input;
1076 Py_UNICODE *output;
1077
1078 size = Tcl_GetCharLength(value);
1079 result = PyUnicode_FromUnicode(NULL, size);
1080 if (!result)
1081 return NULL;
1082 input = Tcl_GetUnicode(value);
1083 output = PyUnicode_AS_UNICODE(result);
1084 while (size--)
1085 *output++ = *input++;
1086 return result;
1087#else
1088 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1089 Tcl_GetCharLength(value));
1090#endif
1091#else
1092 int size;
1093 char *c;
1094 c = Tcl_GetStringFromObj(value, &size);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001095 return PyString_FromStringAndSize(c, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001096#endif
1097 }
1098
1099 return newPyTclObject(value);
1100}
1101
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001102/* This mutex synchronizes inter-thread command calls. */
1103
1104TCL_DECLARE_MUTEX(call_mutex)
1105
1106typedef struct Tkapp_CallEvent {
1107 Tcl_Event ev; /* Must be first */
1108 TkappObject *self;
1109 PyObject *args;
1110 int flags;
1111 PyObject **res;
1112 PyObject **exc_type, **exc_value, **exc_tb;
1113 Tcl_Condition done;
1114} Tkapp_CallEvent;
1115
1116void
1117Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001118{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001119 int i;
1120 for (i = 0; i < objc; i++)
1121 Tcl_DecrRefCount(objv[i]);
1122 if (objv != objStore)
1123 ckfree(FREECAST objv);
1124}
Guido van Rossum18468821994-06-20 07:49:28 +00001125
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001126/* Convert Python objects to Tcl objects. This must happen in the
1127 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001128
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001129static Tcl_Obj**
1130Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1131{
1132 Tcl_Obj **objv = objStore;
Martin v. Löwis7d134952002-12-12 19:05:48 +00001133 int objc = 0, i;
Guido van Rossum212643f1998-04-29 16:22:14 +00001134 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +00001135 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001136
Guido van Rossum212643f1998-04-29 16:22:14 +00001137 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +00001138 objv[0] = AsObj(args);
1139 if (objv[0] == 0)
1140 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001141 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +00001142 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001143 }
1144 else {
Guido van Rossum632de272000-03-29 00:19:50 +00001145 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001146
Guido van Rossum632de272000-03-29 00:19:50 +00001147 if (objc > ARGSZ) {
1148 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1149 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001150 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +00001151 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +00001152 goto finally;
1153 }
1154 }
1155
Guido van Rossum632de272000-03-29 00:19:50 +00001156 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001157 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +00001158 if (v == Py_None) {
1159 objc = i;
1160 break;
1161 }
Guido van Rossum632de272000-03-29 00:19:50 +00001162 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +00001163 if (!objv[i]) {
1164 /* Reset objc, so it attempts to clear
1165 objects only up to i. */
1166 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +00001167 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001168 }
Guido van Rossum632de272000-03-29 00:19:50 +00001169 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001170 }
1171 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001172 *pobjc = objc;
1173 return objv;
1174finally:
1175 Tkapp_CallDeallocArgs(objv, objStore, objc);
1176 return NULL;
1177}
Guido van Rossum212643f1998-04-29 16:22:14 +00001178
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001179/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001180
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001181static PyObject*
1182Tkapp_CallResult(TkappObject *self)
1183{
1184 PyObject *res = NULL;
1185 if(self->wantobjects) {
1186 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001187 /* Not sure whether the IncrRef is necessary, but something
1188 may overwrite the interpreter result while we are
1189 converting it. */
1190 Tcl_IncrRefCount(value);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001191 res = FromObj((PyObject*)self, value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001192 Tcl_DecrRefCount(value);
1193 } else {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001194 const char *s = Tcl_GetStringResult(self->interp);
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001195 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001196
Guido van Rossum990f5c62000-05-04 15:07:16 +00001197 /* If the result contains any bytes with the top bit set,
1198 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001199#ifdef Py_USING_UNICODE
Guido van Rossum990f5c62000-05-04 15:07:16 +00001200 while (*p != '\0') {
1201 if (*p & 0x80)
1202 break;
1203 p++;
1204 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001205
Guido van Rossum990f5c62000-05-04 15:07:16 +00001206 if (*p == '\0')
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001207 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum990f5c62000-05-04 15:07:16 +00001208 else {
1209 /* Convert UTF-8 to Unicode string */
1210 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +00001211 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
1212 if (res == NULL) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001213 PyErr_Clear();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001214 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +00001215 }
Guido van Rossum990f5c62000-05-04 15:07:16 +00001216 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001217#else
1218 p = strchr(p, '\0');
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001219 res = PyString_FromStringAndSize(s, (int)(p-s));
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001220#endif
Guido van Rossum990f5c62000-05-04 15:07:16 +00001221 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001222 return res;
1223}
Guido van Rossum632de272000-03-29 00:19:50 +00001224
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001225/* Tkapp_CallProc is the event procedure that is executed in the context of
1226 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1227 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001228
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001229static int
1230Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1231{
1232 Tcl_Obj *objStore[ARGSZ];
1233 Tcl_Obj **objv;
1234 int objc;
1235 int i;
1236 ENTER_PYTHON
1237 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1238 if (!objv) {
1239 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1240 *(e->res) = NULL;
1241 }
1242 LEAVE_PYTHON
1243 if (!objv)
1244 goto done;
1245 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1246 ENTER_PYTHON
1247 if (i == TCL_ERROR) {
1248 *(e->res) = NULL;
1249 *(e->exc_type) = NULL;
1250 *(e->exc_tb) = NULL;
1251 *(e->exc_value) = PyObject_CallFunction(
1252 Tkinter_TclError, "s",
1253 Tcl_GetStringResult(e->self->interp));
1254 }
1255 else {
1256 *(e->res) = Tkapp_CallResult(e->self);
1257 }
1258 LEAVE_PYTHON
1259 done:
1260 /* Wake up calling thread. */
1261 Tcl_MutexLock(&call_mutex);
1262 Tcl_ConditionNotify(&e->done);
1263 Tcl_MutexUnlock(&call_mutex);
1264 return 1;
1265}
1266
1267/* This is the main entry point for calling a Tcl command.
1268 It supports three cases, with regard to threading:
1269 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1270 the context of the calling thread.
1271 2. Tcl is threaded, caller of the command is in the interpreter thread:
1272 Execute the command in the calling thread. Since the Tcl lock will
1273 not be used, we can merge that with case 1.
1274 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1275 the interpreter thread. Allocation of Tcl objects needs to occur in the
1276 interpreter thread, so we ship the PyObject* args to the target thread,
1277 and perform processing there. */
1278
1279static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001280Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001281{
1282 Tcl_Obj *objStore[ARGSZ];
1283 Tcl_Obj **objv = NULL;
1284 int objc, i;
1285 PyObject *res = NULL;
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001286 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001287 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
1288 int flags = TCL_EVAL_DIRECT;
1289
Kurt B. Kaiserd67a3b92007-07-05 22:03:39 +00001290 /* If args is a single tuple, replace with contents of tuple */
1291 if (1 == PyTuple_Size(args)){
1292 PyObject* item = PyTuple_GetItem(args, 0);
1293 if (PyTuple_Check(item))
1294 args = item;
1295 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001296#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001297 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1298 /* We cannot call the command directly. Instead, we must
1299 marshal the parameters to the interpreter thread. */
1300 Tkapp_CallEvent *ev;
1301 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001302 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001303 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001304 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1305 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1306 ev->self = self;
1307 ev->args = args;
1308 ev->res = &res;
1309 ev->exc_type = &exc_type;
1310 ev->exc_value = &exc_value;
1311 ev->exc_tb = &exc_tb;
1312 ev->done = (Tcl_Condition)0;
1313
1314 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &call_mutex);
1315
1316 if (res == NULL) {
1317 if (exc_type)
1318 PyErr_Restore(exc_type, exc_value, exc_tb);
1319 else
1320 PyErr_SetObject(Tkinter_TclError, exc_value);
1321 }
1322 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001323 else
1324#endif
1325 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001326
1327 objv = Tkapp_CallArgs(args, objStore, &objc);
1328 if (!objv)
1329 return NULL;
1330
1331 ENTER_TCL
1332
1333 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1334
1335 ENTER_OVERLAP
1336
1337 if (i == TCL_ERROR)
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001338 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001339 else
1340 res = Tkapp_CallResult(self);
1341
1342 LEAVE_OVERLAP_TCL
1343
1344 Tkapp_CallDeallocArgs(objv, objStore, objc);
1345 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001346 return res;
1347}
1348
1349
1350static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001351Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001352{
Guido van Rossum212643f1998-04-29 16:22:14 +00001353 /* Could do the same here as for Tkapp_Call(), but this is not used
1354 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1355 way for the user to do what all its Global* variants do (save and
1356 reset the scope pointer, call the local version, restore the saved
1357 scope pointer). */
1358
Guido van Rossum62320c91998-06-15 04:36:09 +00001359 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001360 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001361
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001362 CHECK_TCL_APPARTMENT;
1363
Guido van Rossum62320c91998-06-15 04:36:09 +00001364 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001365 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001366 int err;
1367 ENTER_TCL
1368 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001369 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001370 if (err == TCL_ERROR)
1371 res = Tkinter_Error(self);
1372 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001373 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001374 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001375 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001376 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001377
1378 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001379}
1380
1381static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001382Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001383{
Barry Warsawfa701a81997-01-16 00:15:11 +00001384 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001385 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001386 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001387
Guido van Rossum43713e52000-02-29 13:59:29 +00001388 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001389 return NULL;
1390
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001391 CHECK_TCL_APPARTMENT;
1392
Guido van Rossum00d93061998-05-28 23:06:38 +00001393 ENTER_TCL
1394 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001395 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001396 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001397 res = Tkinter_Error(self);
1398 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001399 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001400 LEAVE_OVERLAP_TCL
1401 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001402}
1403
1404static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001405Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001406{
Barry Warsawfa701a81997-01-16 00:15:11 +00001407 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001408 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001409 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001410
Guido van Rossum43713e52000-02-29 13:59:29 +00001411 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001412 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001413
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001414 CHECK_TCL_APPARTMENT;
1415
Guido van Rossum00d93061998-05-28 23:06:38 +00001416 ENTER_TCL
1417 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001418 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001419 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001420 res = Tkinter_Error(self);
1421 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001422 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001423 LEAVE_OVERLAP_TCL
1424 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001425}
1426
1427static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001428Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001429{
Barry Warsawfa701a81997-01-16 00:15:11 +00001430 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001431 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001432 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001433
Guido van Rossum43713e52000-02-29 13:59:29 +00001434 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001435 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001436
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001437 CHECK_TCL_APPARTMENT;
1438
Guido van Rossum00d93061998-05-28 23:06:38 +00001439 ENTER_TCL
1440 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001441 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001442 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001443 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001444
Guido van Rossum62320c91998-06-15 04:36:09 +00001445 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001446 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001447 LEAVE_OVERLAP_TCL
1448 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001449}
1450
1451static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001452Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001453{
Barry Warsawfa701a81997-01-16 00:15:11 +00001454 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001455 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001456 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001457
Guido van Rossum35d43371997-08-02 00:09:09 +00001458 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001459 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001460
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001461 CHECK_TCL_APPARTMENT;
1462
Guido van Rossum00d93061998-05-28 23:06:38 +00001463 ENTER_TCL
1464 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001465 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001466 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001467 res = Tkinter_Error(self);
1468 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001469 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001470 LEAVE_OVERLAP_TCL
1471 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001472}
1473
1474static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001475Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001476{
Barry Warsawfa701a81997-01-16 00:15:11 +00001477 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001478
Guido van Rossum43713e52000-02-29 13:59:29 +00001479 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001480 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001481 CHECK_TCL_APPARTMENT;
1482
Guido van Rossum00d93061998-05-28 23:06:38 +00001483 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001484 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001485 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001486
Barry Warsawfa701a81997-01-16 00:15:11 +00001487 Py_INCREF(Py_None);
1488 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001489}
1490
Barry Warsawfa701a81997-01-16 00:15:11 +00001491
1492
Guido van Rossum18468821994-06-20 07:49:28 +00001493/** Tcl Variable **/
1494
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001495TCL_DECLARE_MUTEX(var_mutex)
1496
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001497typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001498typedef struct VarEvent {
1499 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001500 PyObject *self;
1501 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001502 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001503 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001504 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001505 PyObject **exc_type;
1506 PyObject **exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001507 Tcl_Condition cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001508} VarEvent;
1509
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001510static int
1511varname_converter(PyObject *in, void *_out)
1512{
1513 char **out = (char**)_out;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001514 if (PyString_Check(in)) {
1515 *out = PyString_AsString(in);
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001516 return 1;
1517 }
1518 if (PyTclObject_Check(in)) {
1519 *out = PyTclObject_TclString(in);
1520 return 1;
1521 }
1522 /* XXX: Should give diagnostics. */
1523 return 0;
1524}
1525
Martin v. Löwis111c1802008-06-13 07:47:47 +00001526static void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001527var_perform(VarEvent *ev)
1528{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001529 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1530 if (!*(ev->res)) {
1531 PyObject *exc, *val, *tb;
1532 PyErr_Fetch(&exc, &val, &tb);
1533 PyErr_NormalizeException(&exc, &val, &tb);
1534 *(ev->exc_type) = exc;
1535 *(ev->exc_val) = val;
1536 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001537 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001538
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001539}
1540
1541static int
1542var_proc(VarEvent* ev, int flags)
1543{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001544 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001545 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001546 Tcl_MutexLock(&var_mutex);
1547 Tcl_ConditionNotify(&ev->cond);
1548 Tcl_MutexUnlock(&var_mutex);
1549 LEAVE_PYTHON
1550 return 1;
1551}
1552
1553static PyObject*
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001554var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001555{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001556 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisa9656492003-03-30 08:44:58 +00001557#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001558 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001559 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001560 VarEvent *ev;
1561 PyObject *res, *exc_type, *exc_val;
1562
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001563 /* The current thread is not the interpreter thread. Marshal
1564 the call to the interpreter thread, then wait for
1565 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001566 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001567 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001568
1569 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1570
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001571 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001572 ev->args = args;
1573 ev->flags = flags;
1574 ev->func = func;
1575 ev->res = &res;
1576 ev->exc_type = &exc_type;
1577 ev->exc_val = &exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001578 ev->cond = NULL;
1579 ev->ev.proc = (Tcl_EventProc*)var_proc;
1580 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001581 if (!res) {
1582 PyErr_SetObject(exc_type, exc_val);
1583 Py_DECREF(exc_type);
1584 Py_DECREF(exc_val);
1585 return NULL;
1586 }
1587 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001588 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001589#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001590 /* Tcl is not threaded, or this is the interpreter thread. */
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001591 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001592}
1593
Guido van Rossum18468821994-06-20 07:49:28 +00001594static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001595SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001596{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001597 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001598 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001599 PyObject *res = NULL;
1600 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001601
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001602 if (PyArg_ParseTuple(args, "O&O:setvar",
1603 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001604 /* XXX Acquire tcl lock??? */
1605 newval = AsObj(newValue);
1606 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001607 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001608 ENTER_TCL
1609 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1610 newval, flags);
1611 ENTER_OVERLAP
1612 if (!ok)
1613 Tkinter_Error(self);
1614 else {
1615 res = Py_None;
1616 Py_INCREF(res);
1617 }
1618 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001619 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001620 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001621 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001622 if (PyArg_ParseTuple(args, "ssO:setvar",
1623 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001624 /* XXX must hold tcl lock already??? */
1625 newval = AsObj(newValue);
1626 ENTER_TCL
1627 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1628 ENTER_OVERLAP
1629 if (!ok)
1630 Tkinter_Error(self);
1631 else {
1632 res = Py_None;
1633 Py_INCREF(res);
1634 }
1635 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001636 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001637 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001638 return NULL;
1639 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001640 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001641 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001642}
1643
1644static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001645Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001646{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001647 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001648}
1649
1650static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001651Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001652{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001653 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001654}
1655
Barry Warsawfa701a81997-01-16 00:15:11 +00001656
1657
Guido van Rossum18468821994-06-20 07:49:28 +00001658static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001659GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001660{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001661 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001662 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001663 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001664
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001665 if (!PyArg_ParseTuple(args, "O&|s:getvar",
1666 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001667 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001668
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001669 ENTER_TCL
1670 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1671 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001672 if (tres == NULL) {
1673 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1674 } else {
1675 if (((TkappObject*)self)->wantobjects) {
1676 res = FromObj(self, tres);
1677 }
1678 else {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001679 res = PyString_FromString(Tcl_GetString(tres));
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001680 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001681 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001682 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001683 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001684}
1685
1686static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001687Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001688{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001689 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001690}
1691
1692static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001693Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001694{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001695 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001696}
1697
Barry Warsawfa701a81997-01-16 00:15:11 +00001698
1699
Guido van Rossum18468821994-06-20 07:49:28 +00001700static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001701UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001702{
Guido van Rossum35d43371997-08-02 00:09:09 +00001703 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001704 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001705 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001706
Guido van Rossum43713e52000-02-29 13:59:29 +00001707 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001708 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001709
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001710 ENTER_TCL
1711 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1712 ENTER_OVERLAP
1713 if (code == TCL_ERROR)
1714 res = Tkinter_Error(self);
1715 else {
1716 Py_INCREF(Py_None);
1717 res = Py_None;
1718 }
1719 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001720 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001721}
1722
1723static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001724Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001725{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001726 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001727}
1728
1729static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001730Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001731{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001732 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001733}
1734
Barry Warsawfa701a81997-01-16 00:15:11 +00001735
1736
Guido van Rossum18468821994-06-20 07:49:28 +00001737/** Tcl to Python **/
1738
1739static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001740Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001741{
Barry Warsawfa701a81997-01-16 00:15:11 +00001742 char *s;
1743 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001744
Martin v. Löwisffad6332002-11-26 09:28:05 +00001745 if (PyTuple_Size(args) == 1) {
1746 PyObject* o = PyTuple_GetItem(args, 0);
1747 if (PyInt_Check(o)) {
1748 Py_INCREF(o);
1749 return o;
1750 }
1751 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001752 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001753 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001754 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001755 return Tkinter_Error(self);
1756 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001757}
1758
1759static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001760Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001761{
Barry Warsawfa701a81997-01-16 00:15:11 +00001762 char *s;
1763 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001764
Martin v. Löwisffad6332002-11-26 09:28:05 +00001765 if (PyTuple_Size(args) == 1) {
1766 PyObject *o = PyTuple_GetItem(args, 0);
1767 if (PyFloat_Check(o)) {
1768 Py_INCREF(o);
1769 return o;
1770 }
1771 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001772 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001773 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001774 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001775 return Tkinter_Error(self);
1776 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001777}
1778
1779static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001780Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001781{
Barry Warsawfa701a81997-01-16 00:15:11 +00001782 char *s;
1783 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001784
Martin v. Löwisffad6332002-11-26 09:28:05 +00001785 if (PyTuple_Size(args) == 1) {
1786 PyObject *o = PyTuple_GetItem(args, 0);
1787 if (PyInt_Check(o)) {
1788 Py_INCREF(o);
1789 return o;
1790 }
1791 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001792 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001793 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001794 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1795 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001796 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001797}
1798
1799static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001800Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001801{
Barry Warsawfa701a81997-01-16 00:15:11 +00001802 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001803 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001804 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001805
Guido van Rossum43713e52000-02-29 13:59:29 +00001806 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001807 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001808
1809 CHECK_TCL_APPARTMENT;
1810
Guido van Rossum00d93061998-05-28 23:06:38 +00001811 ENTER_TCL
1812 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001813 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001814 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001815 res = Tkinter_Error(self);
1816 else
1817 res = Py_BuildValue("s", Tkapp_Result(self));
1818 LEAVE_OVERLAP_TCL
1819 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001820}
1821
1822static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001823Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001824{
Barry Warsawfa701a81997-01-16 00:15:11 +00001825 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001826 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001827 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001828 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001829
Guido van Rossum43713e52000-02-29 13:59:29 +00001830 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001831 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001832
1833 CHECK_TCL_APPARTMENT;
1834
Guido van Rossum00d93061998-05-28 23:06:38 +00001835 ENTER_TCL
1836 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001837 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001838 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001839 res = Tkinter_Error(self);
1840 else
1841 res = Py_BuildValue("l", v);
1842 LEAVE_OVERLAP_TCL
1843 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001844}
1845
1846static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001847Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001848{
Barry Warsawfa701a81997-01-16 00:15:11 +00001849 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001850 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001851 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001852 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001853
Guido van Rossum43713e52000-02-29 13:59:29 +00001854 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001855 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001856 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001857 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001858 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001859 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001860 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001861 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001862 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001863 res = Tkinter_Error(self);
1864 else
1865 res = Py_BuildValue("d", v);
1866 LEAVE_OVERLAP_TCL
1867 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001868}
1869
1870static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001871Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001872{
Barry Warsawfa701a81997-01-16 00:15:11 +00001873 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001874 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001875 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001876 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001877
Guido van Rossum43713e52000-02-29 13:59:29 +00001878 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001879 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001880 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001881 ENTER_TCL
1882 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001883 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001884 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001885 res = Tkinter_Error(self);
1886 else
1887 res = Py_BuildValue("i", v);
1888 LEAVE_OVERLAP_TCL
1889 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001890}
1891
Barry Warsawfa701a81997-01-16 00:15:11 +00001892
1893
Guido van Rossum18468821994-06-20 07:49:28 +00001894static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001895Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001896{
Barry Warsawfa701a81997-01-16 00:15:11 +00001897 char *list;
1898 int argc;
1899 char **argv;
1900 PyObject *v;
1901 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001902
Martin v. Löwisffad6332002-11-26 09:28:05 +00001903 if (PyTuple_Size(args) == 1) {
1904 v = PyTuple_GetItem(args, 0);
1905 if (PyTuple_Check(v)) {
1906 Py_INCREF(v);
1907 return v;
1908 }
1909 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001910 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001911 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001912
Neal Norwitzd1c55102003-05-29 00:17:03 +00001913 if (Tcl_SplitList(Tkapp_Interp(self), list,
1914 &argc, &argv) == TCL_ERROR) {
1915 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001916 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001917 }
Guido van Rossum18468821994-06-20 07:49:28 +00001918
Barry Warsawfa701a81997-01-16 00:15:11 +00001919 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001920 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001921
Barry Warsawfa701a81997-01-16 00:15:11 +00001922 for (i = 0; i < argc; i++) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001923 PyObject *s = PyString_FromString(argv[i]);
Barry Warsawfa701a81997-01-16 00:15:11 +00001924 if (!s || PyTuple_SetItem(v, i, s)) {
1925 Py_DECREF(v);
1926 v = NULL;
1927 goto finally;
1928 }
1929 }
Guido van Rossum18468821994-06-20 07:49:28 +00001930
Barry Warsawfa701a81997-01-16 00:15:11 +00001931 finally:
1932 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001933 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001934 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001935}
1936
1937static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001938Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001939{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001940 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001941 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001942
Martin v. Löwisffad6332002-11-26 09:28:05 +00001943 if (PyTuple_Size(args) == 1) {
1944 PyObject* o = PyTuple_GetItem(args, 0);
1945 if (PyTuple_Check(o)) {
1946 o = SplitObj(o);
1947 return o;
1948 }
1949 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001950 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001951 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00001952 v = Split(list);
1953 PyMem_Free(list);
1954 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001955}
1956
1957static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001958Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001959{
Barry Warsawfa701a81997-01-16 00:15:11 +00001960 char *s = Merge(args);
1961 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001962
Barry Warsawfa701a81997-01-16 00:15:11 +00001963 if (s) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001964 res = PyString_FromString(s);
Barry Warsawfa701a81997-01-16 00:15:11 +00001965 ckfree(s);
1966 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001967
1968 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001969}
1970
Barry Warsawfa701a81997-01-16 00:15:11 +00001971
1972
Guido van Rossum18468821994-06-20 07:49:28 +00001973/** Tcl Command **/
1974
Guido van Rossum00d93061998-05-28 23:06:38 +00001975/* Client data struct */
1976typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001977 PyObject *self;
1978 PyObject *func;
1979} PythonCmd_ClientData;
1980
1981static int
Fred Drake509d79a2000-07-08 04:04:38 +00001982PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001983{
1984 errorInCmd = 1;
1985 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1986 LEAVE_PYTHON
1987 return TCL_ERROR;
1988}
1989
Guido van Rossum18468821994-06-20 07:49:28 +00001990/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001991 * function or method.
1992 */
Guido van Rossum18468821994-06-20 07:49:28 +00001993static int
Fred Drake509d79a2000-07-08 04:04:38 +00001994PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001995{
Guido van Rossum00d93061998-05-28 23:06:38 +00001996 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00001997 PyObject *self, *func, *arg, *res;
Guido van Rossum2834b972000-10-06 16:58:26 +00001998 int i, rv;
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00001999 Tcl_Obj *obj_res;
Guido van Rossum18468821994-06-20 07:49:28 +00002000
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002001 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002002
Barry Warsawfa701a81997-01-16 00:15:11 +00002003 /* TBD: no error checking here since we know, via the
2004 * Tkapp_CreateCommand() that the client data is a two-tuple
2005 */
Guido van Rossum00d93061998-05-28 23:06:38 +00002006 self = data->self;
2007 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00002008
Barry Warsawfa701a81997-01-16 00:15:11 +00002009 /* Create argument list (argv1, ..., argvN) */
2010 if (!(arg = PyTuple_New(argc - 1)))
2011 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00002012
Barry Warsawfa701a81997-01-16 00:15:11 +00002013 for (i = 0; i < (argc - 1); i++) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002014 PyObject *s = PyString_FromString(argv[i + 1]);
Barry Warsawfa701a81997-01-16 00:15:11 +00002015 if (!s || PyTuple_SetItem(arg, i, s)) {
2016 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00002017 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00002018 }
2019 }
2020 res = PyEval_CallObject(func, arg);
2021 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00002022
Barry Warsawfa701a81997-01-16 00:15:11 +00002023 if (res == NULL)
2024 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00002025
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002026 obj_res = AsObj(res);
2027 if (obj_res == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002028 Py_DECREF(res);
2029 return PythonCmd_Error(interp);
2030 }
Guido van Rossum2834b972000-10-06 16:58:26 +00002031 else {
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002032 Tcl_SetObjResult(Tkapp_Interp(self), obj_res);
Guido van Rossum2834b972000-10-06 16:58:26 +00002033 rv = TCL_OK;
2034 }
2035
Barry Warsawfa701a81997-01-16 00:15:11 +00002036 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00002037
Guido van Rossum00d93061998-05-28 23:06:38 +00002038 LEAVE_PYTHON
2039
Guido van Rossum2834b972000-10-06 16:58:26 +00002040 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002041}
2042
2043static void
Fred Drake509d79a2000-07-08 04:04:38 +00002044PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002045{
Guido van Rossum00d93061998-05-28 23:06:38 +00002046 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2047
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002048 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002049 Py_XDECREF(data->self);
2050 Py_XDECREF(data->func);
2051 PyMem_DEL(data);
2052 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002053}
2054
Barry Warsawfa701a81997-01-16 00:15:11 +00002055
2056
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002057
2058TCL_DECLARE_MUTEX(command_mutex)
2059
2060typedef struct CommandEvent{
2061 Tcl_Event ev;
2062 Tcl_Interp* interp;
2063 char *name;
2064 int create;
2065 int *status;
2066 ClientData *data;
2067 Tcl_Condition done;
2068} CommandEvent;
2069
2070static int
2071Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002072{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002073 if (ev->create)
2074 *ev->status = Tcl_CreateCommand(
2075 ev->interp, ev->name, PythonCmd,
2076 ev->data, PythonCmdDelete) == NULL;
2077 else
2078 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2079 Tcl_MutexLock(&command_mutex);
2080 Tcl_ConditionNotify(&ev->done);
2081 Tcl_MutexUnlock(&command_mutex);
2082 return 1;
2083}
2084
2085static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002086Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002087{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002088 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002089 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002090 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002091 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002092 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002093
Guido van Rossum43713e52000-02-29 13:59:29 +00002094 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002095 return NULL;
2096 if (!PyCallable_Check(func)) {
2097 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002098 return NULL;
2099 }
Guido van Rossum18468821994-06-20 07:49:28 +00002100
Martin v. Löwisa9656492003-03-30 08:44:58 +00002101#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002102 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002103 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002104 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002105#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002106
Guido van Rossum00d93061998-05-28 23:06:38 +00002107 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002108 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002109 return PyErr_NoMemory();
Neal Norwitzce5b3c32006-07-16 02:02:57 +00002110 Py_INCREF(self);
2111 Py_INCREF(func);
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002112 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002113 data->func = func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002114
2115 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2116 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2117 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2118 ev->interp = self->interp;
2119 ev->create = 1;
2120 ev->name = cmdName;
2121 ev->data = (ClientData)data;
2122 ev->status = &err;
2123 ev->done = NULL;
2124 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
2125 }
2126 else {
2127 ENTER_TCL
2128 err = Tcl_CreateCommand(
2129 Tkapp_Interp(self), cmdName, PythonCmd,
2130 (ClientData)data, PythonCmdDelete) == NULL;
2131 LEAVE_TCL
2132 }
2133 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002134 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002135 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002136 return NULL;
2137 }
Guido van Rossum18468821994-06-20 07:49:28 +00002138
Barry Warsawfa701a81997-01-16 00:15:11 +00002139 Py_INCREF(Py_None);
2140 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002141}
2142
Barry Warsawfa701a81997-01-16 00:15:11 +00002143
2144
Guido van Rossum18468821994-06-20 07:49:28 +00002145static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002146Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002147{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002148 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002149 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002150 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002151
Guido van Rossum43713e52000-02-29 13:59:29 +00002152 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002153 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002154 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2155 CommandEvent *ev;
2156 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2157 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2158 ev->interp = self->interp;
2159 ev->create = 0;
2160 ev->name = cmdName;
2161 ev->status = &err;
2162 ev->done = NULL;
2163 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done,
2164 &command_mutex);
2165 }
2166 else {
2167 ENTER_TCL
2168 err = Tcl_DeleteCommand(self->interp, cmdName);
2169 LEAVE_TCL
2170 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002171 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002172 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2173 return NULL;
2174 }
2175 Py_INCREF(Py_None);
2176 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002177}
2178
Barry Warsawfa701a81997-01-16 00:15:11 +00002179
2180
Guido van Rossum00d93061998-05-28 23:06:38 +00002181#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002182/** File Handler **/
2183
Guido van Rossum00d93061998-05-28 23:06:38 +00002184typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002185 PyObject *func;
2186 PyObject *file;
2187 int id;
2188 struct _fhcdata *next;
2189} FileHandler_ClientData;
2190
2191static FileHandler_ClientData *HeadFHCD;
2192
2193static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002194NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002195{
2196 FileHandler_ClientData *p;
2197 p = PyMem_NEW(FileHandler_ClientData, 1);
2198 if (p != NULL) {
2199 Py_XINCREF(func);
2200 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002201 p->func = func;
2202 p->file = file;
2203 p->id = id;
2204 p->next = HeadFHCD;
2205 HeadFHCD = p;
2206 }
2207 return p;
2208}
2209
2210static void
Fred Drake509d79a2000-07-08 04:04:38 +00002211DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002212{
2213 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002214
2215 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002216 while ((p = *pp) != NULL) {
2217 if (p->id == id) {
2218 *pp = p->next;
2219 Py_XDECREF(p->func);
2220 Py_XDECREF(p->file);
2221 PyMem_DEL(p);
2222 }
2223 else
2224 pp = &p->next;
2225 }
2226}
2227
Guido van Rossuma597dde1995-01-10 20:56:29 +00002228static void
Fred Drake509d79a2000-07-08 04:04:38 +00002229FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002230{
Guido van Rossum00d93061998-05-28 23:06:38 +00002231 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002232 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002233
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002234 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002235 func = data->func;
2236 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002237
Barry Warsawfa701a81997-01-16 00:15:11 +00002238 arg = Py_BuildValue("(Oi)", file, (long) mask);
2239 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002240 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002241
2242 if (res == NULL) {
2243 errorInCmd = 1;
2244 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2245 }
2246 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002247 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002248}
2249
Guido van Rossum18468821994-06-20 07:49:28 +00002250static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002251Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2252 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002253{
Guido van Rossum00d93061998-05-28 23:06:38 +00002254 FileHandler_ClientData *data;
2255 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002256 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002257
Guilherme Poloe7f14032009-01-03 21:51:09 +00002258 if (!self && Py_Py3kWarningFlag) {
2259 if (PyErr_Warn(PyExc_DeprecationWarning,
2260 "_tkinter.createfilehandler is gone in 3.x") < 0)
2261 return NULL;
2262 }
2263
Guido van Rossum2834b972000-10-06 16:58:26 +00002264 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2265 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002266 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002267
Martin v. Löwisa9656492003-03-30 08:44:58 +00002268#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002269 if (!self && !tcl_lock) {
2270 /* We don't have the Tcl lock since Tcl is threaded. */
2271 PyErr_SetString(PyExc_RuntimeError,
2272 "_tkinter.createfilehandler not supported "
2273 "for threaded Tcl");
2274 return NULL;
2275 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002276#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002277
2278 if (self) {
2279 CHECK_TCL_APPARTMENT;
2280 }
2281
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002282 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002283 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002284 return NULL;
2285 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002286 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002287 return NULL;
2288 }
2289
Guido van Rossuma80649b2000-03-28 20:07:05 +00002290 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002291 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002292 return NULL;
2293
Barry Warsawfa701a81997-01-16 00:15:11 +00002294 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002295 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002296 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002297 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002298 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002299 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002300}
2301
2302static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002303Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002304{
Barry Warsawfa701a81997-01-16 00:15:11 +00002305 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002306 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002307
Guilherme Poloe7f14032009-01-03 21:51:09 +00002308 if (!self && Py_Py3kWarningFlag) {
2309 if (PyErr_Warn(PyExc_DeprecationWarning,
2310 "_tkinter.deletefilehandler is gone in 3.x") < 0)
2311 return NULL;
2312 }
2313
Guido van Rossum43713e52000-02-29 13:59:29 +00002314 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002315 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002316
Martin v. Löwisa9656492003-03-30 08:44:58 +00002317#ifdef WITH_THREAD
Neal Norwitz12e22172003-03-03 21:16:39 +00002318 if (!self && !tcl_lock) {
2319 /* We don't have the Tcl lock since Tcl is threaded. */
2320 PyErr_SetString(PyExc_RuntimeError,
2321 "_tkinter.deletefilehandler not supported "
2322 "for threaded Tcl");
2323 return NULL;
2324 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002325#endif
Neal Norwitz12e22172003-03-03 21:16:39 +00002326
2327 if (self) {
2328 CHECK_TCL_APPARTMENT;
2329 }
2330
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002331 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002332 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002333 return NULL;
2334
Guido van Rossuma80649b2000-03-28 20:07:05 +00002335 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002336
Barry Warsawfa701a81997-01-16 00:15:11 +00002337 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002338 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002339 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002340 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002341 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002342 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002343}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002344#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002345
Barry Warsawfa701a81997-01-16 00:15:11 +00002346
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002347/**** Tktt Object (timer token) ****/
2348
Jeremy Hylton938ace62002-07-17 16:30:39 +00002349static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002350
Guido van Rossum00d93061998-05-28 23:06:38 +00002351typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002352 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002353 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002354 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002355} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002356
2357static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002358Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002359{
Barry Warsawfa701a81997-01-16 00:15:11 +00002360 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002361 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002362
Guido van Rossum43713e52000-02-29 13:59:29 +00002363 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002364 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002365 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002366 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002367 v->token = NULL;
2368 }
2369 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002370 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002371 Py_DECREF(func);
2372 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002373 }
2374 Py_INCREF(Py_None);
2375 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002376}
2377
2378static PyMethodDef Tktt_methods[] =
2379{
Neal Norwitzb0493252002-03-31 14:44:22 +00002380 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002381 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002382};
2383
2384static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002385Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002386{
Barry Warsawfa701a81997-01-16 00:15:11 +00002387 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002388
Guido van Rossumb18618d2000-05-03 23:44:39 +00002389 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002390 if (v == NULL)
2391 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002392
Guido van Rossum00d93061998-05-28 23:06:38 +00002393 Py_INCREF(func);
2394 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002395 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002396
2397 /* Extra reference, deleted when called or when handler is deleted */
2398 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002399 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002400}
2401
2402static void
Fred Drake509d79a2000-07-08 04:04:38 +00002403Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002404{
Guido van Rossum00d93061998-05-28 23:06:38 +00002405 TkttObject *v = (TkttObject *)self;
2406 PyObject *func = v->func;
2407
2408 Py_XDECREF(func);
2409
Guido van Rossumb18618d2000-05-03 23:44:39 +00002410 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002411}
2412
Guido van Rossum597ac201998-05-12 14:36:19 +00002413static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002414Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002415{
Barry Warsawfa701a81997-01-16 00:15:11 +00002416 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002417 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002418
Tim Peters885d4572001-11-28 20:27:42 +00002419 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002420 v->func == NULL ? ", handler deleted" : "");
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002421 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002422}
2423
2424static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002425Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002426{
Barry Warsawfa701a81997-01-16 00:15:11 +00002427 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002428}
2429
2430static PyTypeObject Tktt_Type =
2431{
Martin v. Löwis68192102007-07-21 06:55:02 +00002432 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002433 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002434 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002435 0, /*tp_itemsize */
2436 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002437 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00002438 Tktt_GetAttr, /*tp_getattr */
2439 0, /*tp_setattr */
2440 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00002441 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002442 0, /*tp_as_number */
2443 0, /*tp_as_sequence */
2444 0, /*tp_as_mapping */
2445 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002446};
2447
Barry Warsawfa701a81997-01-16 00:15:11 +00002448
2449
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002450/** Timer Handler **/
2451
2452static void
Fred Drake509d79a2000-07-08 04:04:38 +00002453TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002454{
Guido van Rossum00d93061998-05-28 23:06:38 +00002455 TkttObject *v = (TkttObject *)clientData;
2456 PyObject *func = v->func;
2457 PyObject *res;
2458
2459 if (func == NULL)
2460 return;
2461
2462 v->func = NULL;
2463
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002464 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002465
2466 res = PyEval_CallObject(func, NULL);
2467 Py_DECREF(func);
2468 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002469
Barry Warsawfa701a81997-01-16 00:15:11 +00002470 if (res == NULL) {
2471 errorInCmd = 1;
2472 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2473 }
2474 else
2475 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002476
2477 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002478}
2479
2480static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002481Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002482{
Barry Warsawfa701a81997-01-16 00:15:11 +00002483 int milliseconds;
2484 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002485 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002486
Guilherme Poloe7f14032009-01-03 21:51:09 +00002487 if (!self && Py_Py3kWarningFlag) {
2488 if (PyErr_Warn(PyExc_DeprecationWarning,
2489 "_tkinter.createtimerhandler is gone in 3.x") < 0)
2490 return NULL;
2491 }
2492
Guido van Rossum2834b972000-10-06 16:58:26 +00002493 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2494 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002495 return NULL;
2496 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002497 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002498 return NULL;
2499 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002500
Martin v. Löwisa9656492003-03-30 08:44:58 +00002501#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002502 if (!self && !tcl_lock) {
2503 /* We don't have the Tcl lock since Tcl is threaded. */
2504 PyErr_SetString(PyExc_RuntimeError,
2505 "_tkinter.createtimerhandler not supported "
2506 "for threaded Tcl");
2507 return NULL;
2508 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002509#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002510
2511 if (self) {
2512 CHECK_TCL_APPARTMENT;
2513 }
2514
Guido van Rossum00d93061998-05-28 23:06:38 +00002515 v = Tktt_New(func);
Neal Norwitz5f17d9a2006-08-12 02:33:36 +00002516 if (v) {
2517 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2518 (ClientData)v);
2519 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002520
Guido van Rossum00d93061998-05-28 23:06:38 +00002521 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002522}
2523
Barry Warsawfa701a81997-01-16 00:15:11 +00002524
Guido van Rossum18468821994-06-20 07:49:28 +00002525/** Event Loop **/
2526
Guido van Rossum18468821994-06-20 07:49:28 +00002527static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002528Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002529{
Barry Warsawfa701a81997-01-16 00:15:11 +00002530 int threshold = 0;
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002531 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002532#ifdef WITH_THREAD
2533 PyThreadState *tstate = PyThreadState_Get();
2534#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002535
Guilherme Poloe7f14032009-01-03 21:51:09 +00002536 if (!self && Py_Py3kWarningFlag) {
2537 if (PyErr_Warn(PyExc_DeprecationWarning,
2538 "_tkinter.mainloop is gone in 3.x") < 0)
2539 return NULL;
2540 }
2541
Guido van Rossum43713e52000-02-29 13:59:29 +00002542 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002543 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002544
Martin v. Löwisa9656492003-03-30 08:44:58 +00002545#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002546 if (!self && !tcl_lock) {
2547 /* We don't have the Tcl lock since Tcl is threaded. */
2548 PyErr_SetString(PyExc_RuntimeError,
2549 "_tkinter.mainloop not supported "
2550 "for threaded Tcl");
2551 return NULL;
2552 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002553#endif
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002554
2555 if (self) {
2556 CHECK_TCL_APPARTMENT;
2557 self->dispatching = 1;
2558 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002559
Barry Warsawfa701a81997-01-16 00:15:11 +00002560 quitMainLoop = 0;
2561 while (Tk_GetNumMainWindows() > threshold &&
2562 !quitMainLoop &&
2563 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002564 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002565 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002566
2567#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002568 if (self && self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002569 /* Allow other Python threads to run. */
2570 ENTER_TCL
2571 result = Tcl_DoOneEvent(0);
2572 LEAVE_TCL
2573 }
2574 else {
2575 Py_BEGIN_ALLOW_THREADS
2576 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2577 tcl_tstate = tstate;
2578 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2579 tcl_tstate = NULL;
2580 if(tcl_lock)PyThread_release_lock(tcl_lock);
2581 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002582 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002583 Py_END_ALLOW_THREADS
2584 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002585#else
2586 result = Tcl_DoOneEvent(0);
2587#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002588
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002589 if (PyErr_CheckSignals() != 0) {
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002590 if (self)
2591 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002592 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002593 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002594 if (result < 0)
2595 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002596 }
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002597 if (self)
2598 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002599 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002600
Barry Warsawfa701a81997-01-16 00:15:11 +00002601 if (errorInCmd) {
2602 errorInCmd = 0;
2603 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2604 excInCmd = valInCmd = trbInCmd = NULL;
2605 return NULL;
2606 }
2607 Py_INCREF(Py_None);
2608 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002609}
2610
2611static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002612Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002613{
Guido van Rossum35d43371997-08-02 00:09:09 +00002614 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002615 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002616
Guilherme Poloe7f14032009-01-03 21:51:09 +00002617 if (!self && Py_Py3kWarningFlag) {
2618 if (PyErr_Warn(PyExc_DeprecationWarning,
2619 "_tkinter.dooneevent is gone in 3.x") < 0)
2620 return NULL;
2621 }
2622
Guido van Rossum43713e52000-02-29 13:59:29 +00002623 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002624 return NULL;
2625
Guido van Rossum00d93061998-05-28 23:06:38 +00002626 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002627 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002628 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002629 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002630}
2631
2632static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002633Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002634{
2635
Guilherme Poloe7f14032009-01-03 21:51:09 +00002636 if (!self && Py_Py3kWarningFlag) {
2637 if (PyErr_Warn(PyExc_DeprecationWarning,
2638 "_tkinter.createfilehandler is gone in 3.x") < 0)
2639 return NULL;
2640 }
2641
Guido van Rossum43713e52000-02-29 13:59:29 +00002642 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002643 return NULL;
2644
2645 quitMainLoop = 1;
2646 Py_INCREF(Py_None);
2647 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002648}
2649
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002650static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002651Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002652{
2653
Guido van Rossum43713e52000-02-29 13:59:29 +00002654 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002655 return NULL;
2656
2657 return PyInt_FromLong((long)Tkapp_Interp(self));
2658}
2659
David Aschere2b4b322004-02-18 05:59:53 +00002660static PyObject *
2661Tkapp_TkInit(PyObject *self, PyObject *args)
2662{
Martin v. Löwis86725192006-05-01 06:28:01 +00002663 static int has_failed;
David Aschere2b4b322004-02-18 05:59:53 +00002664 Tcl_Interp *interp = Tkapp_Interp(self);
Neal Norwitz44dbae82004-02-19 02:44:22 +00002665 Tk_Window main_window;
David Aschere2b4b322004-02-18 05:59:53 +00002666 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002667 int err;
Neal Norwitz44dbae82004-02-19 02:44:22 +00002668 main_window = Tk_MainWindow(interp);
David Aschere2b4b322004-02-18 05:59:53 +00002669
Martin v. Löwis86725192006-05-01 06:28:01 +00002670 /* In all current versions of Tk (including 8.4.13), Tk_Init
2671 deadlocks on the second call when the first call failed.
2672 To avoid the deadlock, we just refuse the second call through
2673 a static variable. */
2674 if (has_failed) {
2675 PyErr_SetString(Tkinter_TclError,
2676 "Calling Tk_Init again after a previous call failed might deadlock");
2677 return NULL;
2678 }
2679
David Aschere2b4b322004-02-18 05:59:53 +00002680 /* We want to guard against calling Tk_Init() multiple times */
2681 CHECK_TCL_APPARTMENT;
2682 ENTER_TCL
2683 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2684 ENTER_OVERLAP
2685 if (err == TCL_ERROR) {
Martin v. Löwis86725192006-05-01 06:28:01 +00002686 /* This sets an exception, but we cannot return right
2687 away because we need to exit the overlap first. */
2688 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002689 } else {
2690 _tk_exists = Tkapp_Result(self);
2691 }
2692 LEAVE_OVERLAP_TCL
2693 if (err == TCL_ERROR) {
2694 return NULL;
2695 }
2696 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2697 if (Tk_Init(interp) == TCL_ERROR) {
2698 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
Martin v. Löwis86725192006-05-01 06:28:01 +00002699 has_failed = 1;
David Aschere2b4b322004-02-18 05:59:53 +00002700 return NULL;
2701 }
2702 }
2703 Py_INCREF(Py_None);
2704 return Py_None;
2705}
Barry Warsawfa701a81997-01-16 00:15:11 +00002706
Martin v. Löwisffad6332002-11-26 09:28:05 +00002707static PyObject *
2708Tkapp_WantObjects(PyObject *self, PyObject *args)
2709{
2710
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002711 int wantobjects = -1;
2712 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002713 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002714 if (wantobjects == -1)
2715 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002716 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002717
2718 Py_INCREF(Py_None);
2719 return Py_None;
2720}
2721
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002722static PyObject *
2723Tkapp_WillDispatch(PyObject *self, PyObject *args)
2724{
2725
2726 ((TkappObject*)self)->dispatching = 1;
2727
2728 Py_INCREF(Py_None);
2729 return Py_None;
2730}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002731
Barry Warsawfa701a81997-01-16 00:15:11 +00002732
Guido van Rossum18468821994-06-20 07:49:28 +00002733/**** Tkapp Method List ****/
2734
2735static PyMethodDef Tkapp_methods[] =
2736{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002737 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002738 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Neal Norwitze2e447b2007-05-22 07:16:10 +00002739 {"call", Tkapp_Call, METH_VARARGS},
2740 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002741 {"eval", Tkapp_Eval, METH_VARARGS},
2742 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2743 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2744 {"record", Tkapp_Record, METH_VARARGS},
2745 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2746 {"setvar", Tkapp_SetVar, METH_VARARGS},
2747 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2748 {"getvar", Tkapp_GetVar, METH_VARARGS},
2749 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2750 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2751 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2752 {"getint", Tkapp_GetInt, METH_VARARGS},
2753 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2754 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2755 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2756 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2757 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2758 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2759 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2760 {"split", Tkapp_Split, METH_VARARGS},
Neal Norwitze2e447b2007-05-22 07:16:10 +00002761 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002762 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2763 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002764#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002765 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2766 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002767#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002768 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2769 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2770 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2771 {"quit", Tkapp_Quit, METH_VARARGS},
2772 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002773 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002774 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002775};
2776
Barry Warsawfa701a81997-01-16 00:15:11 +00002777
2778
Guido van Rossum18468821994-06-20 07:49:28 +00002779/**** Tkapp Type Methods ****/
2780
2781static void
Fred Drake509d79a2000-07-08 04:04:38 +00002782Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002783{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002784 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002785 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002786 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002787 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002788 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002789 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002790}
2791
2792static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002793Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002794{
Guido van Rossum35d43371997-08-02 00:09:09 +00002795 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002796}
2797
2798static PyTypeObject Tkapp_Type =
2799{
Martin v. Löwis68192102007-07-21 06:55:02 +00002800 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002801 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002802 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002803 0, /*tp_itemsize */
2804 Tkapp_Dealloc, /*tp_dealloc */
2805 0, /*tp_print */
2806 Tkapp_GetAttr, /*tp_getattr */
2807 0, /*tp_setattr */
2808 0, /*tp_compare */
2809 0, /*tp_repr */
2810 0, /*tp_as_number */
2811 0, /*tp_as_sequence */
2812 0, /*tp_as_mapping */
2813 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002814};
2815
Barry Warsawfa701a81997-01-16 00:15:11 +00002816
2817
Guido van Rossum18468821994-06-20 07:49:28 +00002818/**** Tkinter Module ****/
2819
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002820typedef struct {
2821 PyObject* tuple;
2822 int size; /* current size */
2823 int maxsize; /* allocated size */
2824} FlattenContext;
2825
2826static int
2827_bump(FlattenContext* context, int size)
2828{
Guido van Rossum2834b972000-10-06 16:58:26 +00002829 /* expand tuple to hold (at least) size new items.
2830 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002831
2832 int maxsize = context->maxsize * 2;
2833
2834 if (maxsize < context->size + size)
2835 maxsize = context->size + size;
2836
2837 context->maxsize = maxsize;
2838
Tim Peters4324aa32001-05-28 22:30:08 +00002839 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002840}
2841
2842static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002843_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002844{
2845 /* add tuple or list to argument tuple (recursively) */
2846
2847 int i, size;
2848
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002849 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002850 PyErr_SetString(PyExc_ValueError,
2851 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002852 return 0;
2853 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002854 size = PyList_GET_SIZE(item);
2855 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002856 if (context->size + size > context->maxsize &&
2857 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002858 return 0;
2859 /* copy items to output tuple */
2860 for (i = 0; i < size; i++) {
2861 PyObject *o = PyList_GET_ITEM(item, i);
2862 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002863 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002864 return 0;
2865 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002866 if (context->size + 1 > context->maxsize &&
2867 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002868 return 0;
2869 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002870 PyTuple_SET_ITEM(context->tuple,
2871 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002872 }
2873 }
2874 } else if (PyTuple_Check(item)) {
2875 /* same, for tuples */
2876 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002877 if (context->size + size > context->maxsize &&
2878 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002879 return 0;
2880 for (i = 0; i < size; i++) {
2881 PyObject *o = PyTuple_GET_ITEM(item, i);
2882 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002883 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002884 return 0;
2885 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002886 if (context->size + 1 > context->maxsize &&
2887 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002888 return 0;
2889 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002890 PyTuple_SET_ITEM(context->tuple,
2891 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002892 }
2893 }
2894 } else {
2895 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2896 return 0;
2897 }
2898 return 1;
2899}
2900
2901static PyObject *
2902Tkinter_Flatten(PyObject* self, PyObject* args)
2903{
2904 FlattenContext context;
2905 PyObject* item;
2906
2907 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2908 return NULL;
2909
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002910 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002911 if (context.maxsize <= 0)
2912 return PyTuple_New(0);
2913
2914 context.tuple = PyTuple_New(context.maxsize);
2915 if (!context.tuple)
2916 return NULL;
2917
2918 context.size = 0;
2919
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002920 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002921 return NULL;
2922
Tim Peters4324aa32001-05-28 22:30:08 +00002923 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002924 return NULL;
2925
2926 return context.tuple;
2927}
2928
Guido van Rossum18468821994-06-20 07:49:28 +00002929static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002930Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002931{
Barry Warsawfa701a81997-01-16 00:15:11 +00002932 char *screenName = NULL;
2933 char *baseName = NULL;
2934 char *className = NULL;
2935 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002936 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002937 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002938 int sync = 0; /* pass -sync to wish */
2939 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002940
Guido van Rossum35d43371997-08-02 00:09:09 +00002941 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002942 if (baseName != NULL)
2943 baseName++;
2944 else
2945 baseName = Py_GetProgramName();
2946 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002947
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002948 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002949 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002950 &interactive, &wantobjects, &wantTk,
2951 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00002952 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002953
Barry Warsawfa701a81997-01-16 00:15:11 +00002954 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002955 interactive, wantobjects, wantTk,
2956 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002957}
2958
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002959static PyObject *
2960Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2961{
2962 int new_val;
2963 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2964 return NULL;
2965 if (new_val < 0) {
2966 PyErr_SetString(PyExc_ValueError,
2967 "busywaitinterval must be >= 0");
2968 return NULL;
2969 }
2970 Tkinter_busywaitinterval = new_val;
2971 Py_INCREF(Py_None);
2972 return Py_None;
2973}
2974
2975static char setbusywaitinterval_doc[] =
2976"setbusywaitinterval(n) -> None\n\
2977\n\
2978Set the busy-wait interval in milliseconds between successive\n\
2979calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2980It should be set to a divisor of the maximum time between\n\
2981frames in an animation.";
2982
2983static PyObject *
2984Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2985{
2986 return PyInt_FromLong(Tkinter_busywaitinterval);
2987}
2988
2989static char getbusywaitinterval_doc[] =
2990"getbusywaitinterval() -> int\n\
2991\n\
2992Return the current busy-wait interval between successive\n\
2993calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2994
Guido van Rossum18468821994-06-20 07:49:28 +00002995static PyMethodDef moduleMethods[] =
2996{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002997 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2998 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002999#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003000 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
3001 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00003002#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003003 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
3004 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
3005 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
3006 {"quit", Tkapp_Quit, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003007 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
3008 setbusywaitinterval_doc},
3009 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
3010 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00003011 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00003012};
3013
Guido van Rossum7bf15641998-05-22 18:28:17 +00003014#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003015
3016static int stdin_ready = 0;
3017
Guido van Rossumad4db171998-06-13 13:56:28 +00003018#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00003019static void
Fred Drake509d79a2000-07-08 04:04:38 +00003020MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003021{
3022 stdin_ready = 1;
3023}
Guido van Rossumad4db171998-06-13 13:56:28 +00003024#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003025
Martin v. Löwisa9656492003-03-30 08:44:58 +00003026#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003027static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00003028#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00003029
Guido van Rossum18468821994-06-20 07:49:28 +00003030static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003031EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003032{
Guido van Rossumad4db171998-06-13 13:56:28 +00003033#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00003034 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00003035#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003036#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003037 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003038#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003039 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00003040 errorInCmd = 0;
3041#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00003042 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003043 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00003044#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003045 while (!errorInCmd && !stdin_ready) {
3046 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00003047#ifdef MS_WINDOWS
3048 if (_kbhit()) {
3049 stdin_ready = 1;
3050 break;
3051 }
3052#endif
3053#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00003054 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003055 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00003056 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003057
Guido van Rossum00d93061998-05-28 23:06:38 +00003058 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003059
3060 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003061 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00003062 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003063 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00003064 Py_END_ALLOW_THREADS
3065#else
3066 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003067#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003068
3069 if (result < 0)
3070 break;
3071 }
Guido van Rossumad4db171998-06-13 13:56:28 +00003072#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00003073 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00003074#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003075 if (errorInCmd) {
3076 errorInCmd = 0;
3077 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3078 excInCmd = valInCmd = trbInCmd = NULL;
3079 PyErr_Print();
3080 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003081#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003082 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003083#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003084 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00003085}
Guido van Rossum18468821994-06-20 07:49:28 +00003086
Guido van Rossum00d93061998-05-28 23:06:38 +00003087#endif
3088
Guido van Rossum7bf15641998-05-22 18:28:17 +00003089static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003090EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003091{
Guido van Rossum00d93061998-05-28 23:06:38 +00003092#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003093 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003094#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003095 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003096#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003097 PyOS_InputHook = EventHook;
3098 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003099#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003100}
3101
3102static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003103DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003104{
Guido van Rossum00d93061998-05-28 23:06:38 +00003105#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003106 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3107 PyOS_InputHook = NULL;
3108 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003109#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003110}
3111
Barry Warsawfa701a81997-01-16 00:15:11 +00003112
3113/* all errors will be checked in one fell swoop in init_tkinter() */
3114static void
Fred Drake509d79a2000-07-08 04:04:38 +00003115ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003116{
3117 PyObject *v = PyInt_FromLong(val);
3118 if (v) {
3119 PyDict_SetItemString(d, name, v);
3120 Py_DECREF(v);
3121 }
3122}
3123static void
Fred Drake509d79a2000-07-08 04:04:38 +00003124ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003125{
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003126 PyObject *v = PyString_FromString(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003127 if (v) {
3128 PyDict_SetItemString(d, name, v);
3129 Py_DECREF(v);
3130 }
3131}
3132
3133
Mark Hammond62b1ab12002-07-23 06:31:15 +00003134PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003135init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003136{
Barry Warsawfa701a81997-01-16 00:15:11 +00003137 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00003138
Christian Heimese93237d2007-12-19 02:37:44 +00003139 Py_TYPE(&Tkapp_Type) = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00003140
3141#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003142 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003143#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003144
Barry Warsawfa701a81997-01-16 00:15:11 +00003145 m = Py_InitModule("_tkinter", moduleMethods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003146 if (m == NULL)
3147 return;
Guido van Rossum18468821994-06-20 07:49:28 +00003148
Barry Warsawfa701a81997-01-16 00:15:11 +00003149 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003150 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003151 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003152
Guido van Rossum35d43371997-08-02 00:09:09 +00003153 ins_long(d, "READABLE", TCL_READABLE);
3154 ins_long(d, "WRITABLE", TCL_WRITABLE);
3155 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3156 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3157 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3158 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3159 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3160 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3161 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003162 ins_string(d, "TK_VERSION", TK_VERSION);
3163 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003164
Guido van Rossum83551bf1997-09-13 00:44:23 +00003165 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003166
Christian Heimese93237d2007-12-19 02:37:44 +00003167 Py_TYPE(&Tktt_Type) = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003168 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3169
Christian Heimese93237d2007-12-19 02:37:44 +00003170 Py_TYPE(&PyTclObject_Type) = &PyType_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003171 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003172
3173#ifdef TK_AQUA
3174 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3175 * start waking up. Note that Tcl_FindExecutable will do this, this
3176 * code must be above it! The original warning from
3177 * tkMacOSXAppInit.c is copied below.
3178 *
3179 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3180 * Tcl interpreter for now. It probably should work to do this
3181 * in the other order, but for now it doesn't seem to.
3182 *
3183 */
3184 Tk_MacOSXSetupTkNotifier();
3185#endif
3186
3187
Guido van Rossume187b0e2000-03-27 21:46:29 +00003188 /* This helps the dynamic loader; in Unicode aware Tcl versions
3189 it also helps Tcl find its encodings. */
3190 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00003191
Barry Warsawfa701a81997-01-16 00:15:11 +00003192 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003193 return;
3194
Guido van Rossum43ff8681998-07-14 18:02:13 +00003195#if 0
3196 /* This was not a good idea; through <Destroy> bindings,
3197 Tcl_Finalize() may invoke Python code but at that point the
3198 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003199 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003200#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003201
Guido van Rossum18468821994-06-20 07:49:28 +00003202}