blob: b7d637b5b02e17763b2f95b5870eaf35b194e5a6 [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
265#define Tkapp_Check(v) ((v)->ob_type == &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", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000270(void *) v, ((PyObject *) v)->ob_refcnt))
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{
Guido van Rossum35d43371997-08-02 00:09:09 +0000338 if (PyString_Check(value))
339 return PyString_AsString(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000340 else if (PyUnicode_Check(value)) {
341 PyObject *v = PyUnicode_AsUTF8String(value);
342 if (v == NULL)
343 return NULL;
344 if (PyList_Append(tmp, v) != 0) {
345 Py_DECREF(v);
346 return NULL;
347 }
348 Py_DECREF(v);
349 return PyString_AsString(v);
350 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000351 else {
352 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000353 if (v == NULL)
354 return NULL;
355 if (PyList_Append(tmp, v) != 0) {
356 Py_DECREF(v);
357 return NULL;
358 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000359 Py_DECREF(v);
360 return PyString_AsString(v);
361 }
Guido van Rossum18468821994-06-20 07:49:28 +0000362}
363
Barry Warsawfa701a81997-01-16 00:15:11 +0000364
365
Guido van Rossum18468821994-06-20 07:49:28 +0000366#define ARGSZ 64
367
368static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000369Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000370{
Barry Warsawfa701a81997-01-16 00:15:11 +0000371 PyObject *tmp = NULL;
372 char *argvStore[ARGSZ];
373 char **argv = NULL;
374 int fvStore[ARGSZ];
375 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000376 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000377 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000378
Barry Warsawfa701a81997-01-16 00:15:11 +0000379 if (!(tmp = PyList_New(0)))
380 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000381
Barry Warsawfa701a81997-01-16 00:15:11 +0000382 argv = argvStore;
383 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000384
Barry Warsawfa701a81997-01-16 00:15:11 +0000385 if (args == NULL)
386 argc = 0;
387
388 else if (!PyTuple_Check(args)) {
389 argc = 1;
390 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000391 if (!(argv[0] = AsString(args, tmp)))
392 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000393 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000394 else {
395 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000396
Barry Warsawfa701a81997-01-16 00:15:11 +0000397 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000398 argv = (char **)ckalloc(argc * sizeof(char *));
399 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 if (argv == NULL || fv == NULL) {
401 PyErr_NoMemory();
402 goto finally;
403 }
404 }
405
406 for (i = 0; i < argc; i++) {
407 PyObject *v = PyTuple_GetItem(args, i);
408 if (PyTuple_Check(v)) {
409 fv[i] = 1;
410 if (!(argv[i] = Merge(v)))
411 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000412 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000413 }
414 else if (v == Py_None) {
415 argc = i;
416 break;
417 }
418 else {
419 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000420 if (!(argv[i] = AsString(v, tmp)))
421 goto finally;
422 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000423 }
424 }
Guido van Rossum18468821994-06-20 07:49:28 +0000425 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000426 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000427 if (res == NULL)
428 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000429
Barry Warsawfa701a81997-01-16 00:15:11 +0000430 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000431 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000432 if (fv[i]) {
433 ckfree(argv[i]);
434 }
435 if (argv != argvStore)
436 ckfree(FREECAST argv);
437 if (fv != fvStore)
438 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000439
Barry Warsawfa701a81997-01-16 00:15:11 +0000440 Py_DECREF(tmp);
441 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000442}
443
Barry Warsawfa701a81997-01-16 00:15:11 +0000444
445
Guido van Rossum18468821994-06-20 07:49:28 +0000446static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000447Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000448{
Barry Warsawfa701a81997-01-16 00:15:11 +0000449 int argc;
450 char **argv;
451 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000452
Barry Warsawfa701a81997-01-16 00:15:11 +0000453 if (list == NULL) {
454 Py_INCREF(Py_None);
455 return Py_None;
456 }
Guido van Rossum18468821994-06-20 07:49:28 +0000457
Guido van Rossum00d93061998-05-28 23:06:38 +0000458 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000459 /* Not a list.
460 * Could be a quoted string containing funnies, e.g. {"}.
461 * Return the string itself.
462 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000463 return PyString_FromString(list);
464 }
Guido van Rossum18468821994-06-20 07:49:28 +0000465
Barry Warsawfa701a81997-01-16 00:15:11 +0000466 if (argc == 0)
467 v = PyString_FromString("");
468 else if (argc == 1)
469 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000470 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 int i;
472 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000473
Barry Warsawfa701a81997-01-16 00:15:11 +0000474 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000475 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 Py_DECREF(v);
477 v = NULL;
478 break;
479 }
480 PyTuple_SetItem(v, i, w);
481 }
482 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000483 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000484 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000485}
486
Martin v. Löwisffad6332002-11-26 09:28:05 +0000487/* In some cases, Tcl will still return strings that are supposed to be
488 lists. SplitObj walks through a nested tuple, finding string objects that
489 need to be split. */
490
491PyObject *
492SplitObj(PyObject *arg)
493{
494 if (PyTuple_Check(arg)) {
495 int i, size;
496 PyObject *elem, *newelem, *result;
497
498 size = PyTuple_Size(arg);
499 result = NULL;
500 /* Recursively invoke SplitObj for all tuple items.
501 If this does not return a new object, no action is
502 needed. */
503 for(i = 0; i < size; i++) {
504 elem = PyTuple_GetItem(arg, i);
505 newelem = SplitObj(elem);
506 if (!newelem) {
507 Py_XDECREF(result);
508 return NULL;
509 }
510 if (!result) {
511 int k;
512 if (newelem == elem) {
513 Py_DECREF(newelem);
514 continue;
515 }
516 result = PyTuple_New(size);
517 if (!result)
518 return NULL;
519 for(k = 0; k < i; k++) {
520 elem = PyTuple_GetItem(arg, k);
521 Py_INCREF(elem);
522 PyTuple_SetItem(result, k, elem);
523 }
524 }
525 PyTuple_SetItem(result, i, newelem);
526 }
527 if (result)
528 return result;
529 /* Fall through, returning arg. */
530 }
531 else if (PyString_Check(arg)) {
532 int argc;
533 char **argv;
534 char *list = PyString_AsString(arg);
535
536 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
537 Py_INCREF(arg);
538 return arg;
539 }
540 Tcl_Free(FREECAST argv);
541 if (argc > 1)
542 return Split(PyString_AsString(arg));
543 /* Fall through, returning arg. */
544 }
545 Py_INCREF(arg);
546 return arg;
547}
Barry Warsawfa701a81997-01-16 00:15:11 +0000548
549
Guido van Rossum18468821994-06-20 07:49:28 +0000550/**** Tkapp Object ****/
551
552#ifndef WITH_APPINIT
553int
Fred Drake509d79a2000-07-08 04:04:38 +0000554Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000555{
Barry Warsawfa701a81997-01-16 00:15:11 +0000556 Tk_Window main;
David Aschere2b4b322004-02-18 05:59:53 +0000557 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000558
Barry Warsawfa701a81997-01-16 00:15:11 +0000559 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000560 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000561 return TCL_ERROR;
562 }
David Aschere2b4b322004-02-18 05:59:53 +0000563 _tkinter_skip_tk_init = Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
564 if (_tkinter_skip_tk_init == NULL || strcmp(_tkinter_skip_tk_init, "1") != 0) {
565 main = Tk_MainWindow(interp);
566 if (Tk_Init(interp) == TCL_ERROR) {
567 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
568 return TCL_ERROR;
569 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 }
571 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000572}
573#endif /* !WITH_APPINIT */
574
Guido van Rossum18468821994-06-20 07:49:28 +0000575
Barry Warsawfa701a81997-01-16 00:15:11 +0000576
577
578/* Initialize the Tk application; see the `main' function in
579 * `tkMain.c'.
580 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000581
Thomas Wouters58d05102000-07-24 14:43:35 +0000582static void EnableEventHook(void); /* Forward */
583static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000584
Barry Warsawfa701a81997-01-16 00:15:11 +0000585static TkappObject *
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000586Tkapp_New(char *screenName, char *baseName, char *className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000587 int interactive, int wantobjects, int wantTk, int sync, char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000588{
589 TkappObject *v;
590 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000591
Guido van Rossumb18618d2000-05-03 23:44:39 +0000592 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000593 if (v == NULL)
594 return NULL;
595
596 v->interp = Tcl_CreateInterp();
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000597 v->wantobjects = wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000598 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
599 TCL_GLOBAL_ONLY) != NULL;
600 v->thread_id = Tcl_GetCurrentThread();
601 v->dispatching = 0;
602
603#ifndef TCL_THREADS
604 if (v->threaded) {
605 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
606 Py_DECREF(v);
607 return 0;
608 }
609#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000610#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000611 if (v->threaded && tcl_lock) {
612 /* If Tcl is threaded, we don't need the lock. */
613 PyThread_free_lock(tcl_lock);
614 tcl_lock = NULL;
615 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000616#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000617
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000618 v->BooleanType = Tcl_GetObjType("boolean");
619 v->ByteArrayType = Tcl_GetObjType("bytearray");
620 v->DoubleType = Tcl_GetObjType("double");
621 v->IntType = Tcl_GetObjType("int");
622 v->ListType = Tcl_GetObjType("list");
623 v->ProcBodyType = Tcl_GetObjType("procbody");
624 v->StringType = Tcl_GetObjType("string");
625
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000626 /* Delete the 'exit' command, which can screw things up */
627 Tcl_DeleteCommand(v->interp, "exit");
628
Barry Warsawfa701a81997-01-16 00:15:11 +0000629 if (screenName != NULL)
630 Tcl_SetVar2(v->interp, "env", "DISPLAY",
631 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000632
Barry Warsawfa701a81997-01-16 00:15:11 +0000633 if (interactive)
634 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
635 else
636 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000637
Barry Warsawfa701a81997-01-16 00:15:11 +0000638 /* This is used to get the application class for Tk 4.1 and up */
639 argv0 = (char*)ckalloc(strlen(className) + 1);
640 if (!argv0) {
641 PyErr_NoMemory();
642 Py_DECREF(v);
643 return NULL;
644 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000645
Barry Warsawfa701a81997-01-16 00:15:11 +0000646 strcpy(argv0, className);
Neal Norwitz9dbc7dd2005-12-19 06:08:59 +0000647 if (isupper(Py_CHARMASK(argv0[0])))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000648 argv0[0] = tolower(Py_CHARMASK(argv0[0]));
Barry Warsawfa701a81997-01-16 00:15:11 +0000649 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
650 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000651
David Aschere2b4b322004-02-18 05:59:53 +0000652 if (! wantTk) {
653 Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
654 }
655
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000656 /* some initial arguments need to be in argv */
657 if (sync || use) {
Tim Peters51fa3b72004-08-04 02:16:48 +0000658 char *args;
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000659 int len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000660
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000661 if (sync)
662 len += sizeof "-sync";
663 if (use)
664 len += strlen(use) + sizeof "-use ";
665
Tim Peters51fa3b72004-08-04 02:16:48 +0000666 args = (char*)ckalloc(len);
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000667 if (!args) {
668 PyErr_NoMemory();
669 Py_DECREF(v);
670 return NULL;
671 }
672
673 args[0] = '\0';
674 if (sync)
675 strcat(args, "-sync");
676 if (use) {
677 if (sync)
678 strcat(args, " ");
679 strcat(args, "-use ");
680 strcat(args, use);
681 }
682
683 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
684 ckfree(args);
685 }
686
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000687 if (Tcl_AppInit(v->interp) != TCL_OK) {
688 PyObject *result = Tkinter_Error((PyObject *)v);
689 Py_DECREF((PyObject *)v);
690 return (TkappObject *)result;
691 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000692
Guido van Rossum7bf15641998-05-22 18:28:17 +0000693 EnableEventHook();
694
Barry Warsawfa701a81997-01-16 00:15:11 +0000695 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000696}
697
Barry Warsawfa701a81997-01-16 00:15:11 +0000698
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000699static void
700Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
701 Tcl_Condition *cond, Tcl_Mutex *mutex)
702{
703 Py_BEGIN_ALLOW_THREADS;
704 Tcl_MutexLock(mutex);
705 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
706 Tcl_ThreadAlert(self->thread_id);
707 Tcl_ConditionWait(cond, mutex, NULL);
708 Tcl_MutexUnlock(mutex);
709 Py_END_ALLOW_THREADS
710}
711
Barry Warsawfa701a81997-01-16 00:15:11 +0000712
Guido van Rossum18468821994-06-20 07:49:28 +0000713/** Tcl Eval **/
714
Martin v. Löwisffad6332002-11-26 09:28:05 +0000715typedef struct {
716 PyObject_HEAD
717 Tcl_Obj *value;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000718 PyObject *string; /* This cannot cause cycles. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000719} PyTclObject;
720
Neal Norwitz227b5332006-03-22 09:28:35 +0000721static PyTypeObject PyTclObject_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000722#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
723
724static PyObject *
725newPyTclObject(Tcl_Obj *arg)
726{
727 PyTclObject *self;
728 self = PyObject_New(PyTclObject, &PyTclObject_Type);
729 if (self == NULL)
730 return NULL;
731 Tcl_IncrRefCount(arg);
732 self->value = arg;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000733 self->string = NULL;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000734 return (PyObject*)self;
735}
736
737static void
738PyTclObject_dealloc(PyTclObject *self)
739{
740 Tcl_DecrRefCount(self->value);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000741 Py_XDECREF(self->string);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000742 PyObject_Del(self);
743}
744
745static PyObject *
746PyTclObject_str(PyTclObject *self)
747{
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000748 if (self->string && PyString_Check(self->string)) {
749 Py_INCREF(self->string);
750 return self->string;
751 }
752 /* XXX Could cache value if it is an ASCII string. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000753 return PyString_FromString(Tcl_GetString(self->value));
754}
755
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000756static char*
757PyTclObject_TclString(PyObject *self)
758{
759 return Tcl_GetString(((PyTclObject*)self)->value);
760}
761
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000762/* Like _str, but create Unicode if necessary. */
Martin v. Löwis39195712003-01-04 00:33:13 +0000763PyDoc_STRVAR(PyTclObject_string__doc__,
764"the string representation of this object, either as string or Unicode");
765
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000766static PyObject *
767PyTclObject_string(PyTclObject *self, void *ignored)
768{
769 char *s;
770 int i, len;
771 if (!self->string) {
772 s = Tcl_GetStringFromObj(self->value, &len);
773 for (i = 0; i < len; i++)
774 if (s[i] & 0x80)
775 break;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000776 if (i == len)
777 /* It is an ASCII string. */
778 self->string = PyString_FromStringAndSize(s, len);
779 else {
780 self->string = PyUnicode_DecodeUTF8(s, len, "strict");
781 if (!self->string) {
782 PyErr_Clear();
783 self->string = PyString_FromStringAndSize(s, len);
784 }
785 }
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000786 if (!self->string)
787 return NULL;
788 }
789 Py_INCREF(self->string);
790 return self->string;
791}
792
Martin v. Löwis39195712003-01-04 00:33:13 +0000793PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode");
794
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000795static PyObject *
796PyTclObject_unicode(PyTclObject *self, void *ignored)
797{
798 char *s;
799 int len;
800 if (self->string && PyUnicode_Check(self->string)) {
801 Py_INCREF(self->string);
802 return self->string;
803 }
804 /* XXX Could chache result if it is non-ASCII. */
805 s = Tcl_GetStringFromObj(self->value, &len);
806 return PyUnicode_DecodeUTF8(s, len, "strict");
807}
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000808
Martin v. Löwisffad6332002-11-26 09:28:05 +0000809static PyObject *
810PyTclObject_repr(PyTclObject *self)
811{
Walter Dörwald7569dfe2007-05-19 21:49:49 +0000812 return PyUnicode_FromFormat("<%s object at %p>",
813 self->value->typePtr->name, self->value);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000814}
815
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000816static int
817PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
818{
819 int res;
820 res = strcmp(Tcl_GetString(self->value),
821 Tcl_GetString(other->value));
822 if (res < 0) return -1;
823 if (res > 0) return 1;
824 return 0;
825}
826
Martin v. Löwis39195712003-01-04 00:33:13 +0000827PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
828
Martin v. Löwisffad6332002-11-26 09:28:05 +0000829static PyObject*
830get_typename(PyTclObject* obj, void* ignored)
831{
832 return PyString_FromString(obj->value->typePtr->name);
833}
834
Martin v. Löwis39195712003-01-04 00:33:13 +0000835
Martin v. Löwisffad6332002-11-26 09:28:05 +0000836static PyGetSetDef PyTclObject_getsetlist[] = {
Martin v. Löwis39195712003-01-04 00:33:13 +0000837 {"typename", (getter)get_typename, NULL, get_typename__doc__},
838 {"string", (getter)PyTclObject_string, NULL,
839 PyTclObject_string__doc__},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000840 {0},
841};
842
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000843static PyMethodDef PyTclObject_methods[] = {
844 {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS,
Martin v. Löwis39195712003-01-04 00:33:13 +0000845 PyTclObject_unicode__doc__},
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000846 {0}
847};
848
Neal Norwitz227b5332006-03-22 09:28:35 +0000849static PyTypeObject PyTclObject_Type = {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000850 PyObject_HEAD_INIT(NULL)
851 0, /*ob_size*/
852 "_tkinter.Tcl_Obj", /*tp_name*/
853 sizeof(PyTclObject), /*tp_basicsize*/
854 0, /*tp_itemsize*/
855 /* methods */
856 (destructor)PyTclObject_dealloc, /*tp_dealloc*/
857 0, /*tp_print*/
858 0, /*tp_getattr*/
859 0, /*tp_setattr*/
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000860 (cmpfunc)PyTclObject_cmp, /*tp_compare*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000861 (reprfunc)PyTclObject_repr, /*tp_repr*/
862 0, /*tp_as_number*/
863 0, /*tp_as_sequence*/
864 0, /*tp_as_mapping*/
865 0, /*tp_hash*/
866 0, /*tp_call*/
867 (reprfunc)PyTclObject_str, /*tp_str*/
Jason Tishlerfb8595d2003-01-06 12:41:26 +0000868 PyObject_GenericGetAttr,/*tp_getattro*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000869 0, /*tp_setattro*/
870 0, /*tp_as_buffer*/
871 Py_TPFLAGS_DEFAULT, /*tp_flags*/
872 0, /*tp_doc*/
873 0, /*tp_traverse*/
874 0, /*tp_clear*/
875 0, /*tp_richcompare*/
876 0, /*tp_weaklistoffset*/
877 0, /*tp_iter*/
878 0, /*tp_iternext*/
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000879 PyTclObject_methods, /*tp_methods*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000880 0, /*tp_members*/
881 PyTclObject_getsetlist, /*tp_getset*/
882 0, /*tp_base*/
883 0, /*tp_dict*/
884 0, /*tp_descr_get*/
885 0, /*tp_descr_set*/
886 0, /*tp_dictoffset*/
887 0, /*tp_init*/
888 0, /*tp_alloc*/
889 0, /*tp_new*/
890 0, /*tp_free*/
891 0, /*tp_is_gc*/
892};
893
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000894static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000895AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000896{
897 Tcl_Obj *result;
898
899 if (PyString_Check(value))
900 return Tcl_NewStringObj(PyString_AS_STRING(value),
901 PyString_GET_SIZE(value));
Martin v. Löwis70c3dda2003-01-22 09:17:38 +0000902 else if (PyBool_Check(value))
903 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
Guido van Rossumddefaf32007-01-14 03:31:43 +0000904 else if (PyInt_CheckExact(value))
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000905 return Tcl_NewLongObj(PyInt_AS_LONG(value));
906 else if (PyFloat_Check(value))
907 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
908 else if (PyTuple_Check(value)) {
909 Tcl_Obj **argv = (Tcl_Obj**)
910 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
911 int i;
912 if(!argv)
913 return 0;
914 for(i=0;i<PyTuple_Size(value);i++)
915 argv[i] = AsObj(PyTuple_GetItem(value,i));
916 result = Tcl_NewListObj(PyTuple_Size(value), argv);
917 ckfree(FREECAST argv);
918 return result;
919 }
920 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000921 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000922 Py_ssize_t size = PyUnicode_GET_SIZE(value);
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000923 /* This #ifdef assumes that Tcl uses UCS-2.
924 See TCL_UTF_MAX test above. */
Martin v. Löwis6f29ff32003-04-16 20:34:55 +0000925#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000926 Tcl_UniChar *outbuf;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000927 Py_ssize_t i;
928 assert(size < size * sizeof(Tcl_UniChar));
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000929 outbuf = (Tcl_UniChar*)ckalloc(size * sizeof(Tcl_UniChar));
930 if (!outbuf) {
931 PyErr_NoMemory();
932 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000933 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000934 for (i = 0; i < size; i++) {
935 if (inbuf[i] >= 0x10000) {
936 /* Tcl doesn't do UTF-16, yet. */
937 PyErr_SetString(PyExc_ValueError,
938 "unsupported character");
939 ckfree(FREECAST outbuf);
940 return NULL;
941 }
942 outbuf[i] = inbuf[i];
943 }
944 result = Tcl_NewUnicodeObj(outbuf, size);
945 ckfree(FREECAST outbuf);
946 return result;
947#else
948 return Tcl_NewUnicodeObj(inbuf, size);
949#endif
950
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000951 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000952 else if(PyTclObject_Check(value)) {
953 Tcl_Obj *v = ((PyTclObject*)value)->value;
954 Tcl_IncrRefCount(v);
955 return v;
956 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000957 else {
958 PyObject *v = PyObject_Str(value);
959 if (!v)
960 return 0;
961 result = AsObj(v);
962 Py_DECREF(v);
963 return result;
964 }
965}
966
Martin v. Löwisffad6332002-11-26 09:28:05 +0000967static PyObject*
968FromObj(PyObject* tkapp, Tcl_Obj *value)
969{
970 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000971 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000972
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000973 if (value->typePtr == NULL) {
974 /* If the result contains any bytes with the top bit set,
975 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000976 int i;
977 char *s = value->bytes;
978 int len = value->length;
979 for (i = 0; i < len; i++) {
980 if (value->bytes[i] & 0x80)
981 break;
982 }
983
984 if (i == value->length)
985 result = PyString_FromStringAndSize(s, len);
986 else {
987 /* Convert UTF-8 to Unicode string */
988 result = PyUnicode_DecodeUTF8(s, len, "strict");
989 if (result == NULL) {
990 PyErr_Clear();
991 result = PyString_FromStringAndSize(s, len);
992 }
993 }
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000994 return result;
995 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000996
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000997 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000998 result = value->internalRep.longValue ? Py_True : Py_False;
999 Py_INCREF(result);
1000 return result;
1001 }
1002
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001003 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001004 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +00001005 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001006 return PyString_FromStringAndSize(data, size);
1007 }
1008
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001009 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001010 return PyFloat_FromDouble(value->internalRep.doubleValue);
1011 }
1012
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001013 if (value->typePtr == app->IntType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001014 return PyInt_FromLong(value->internalRep.longValue);
1015 }
1016
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001017 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001018 int size;
1019 int i, status;
1020 PyObject *elem;
1021 Tcl_Obj *tcl_elem;
1022
1023 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
1024 if (status == TCL_ERROR)
1025 return Tkinter_Error(tkapp);
1026 result = PyTuple_New(size);
1027 if (!result)
1028 return NULL;
1029 for (i = 0; i < size; i++) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001030 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
Martin v. Löwisffad6332002-11-26 09:28:05 +00001031 value, i, &tcl_elem);
1032 if (status == TCL_ERROR) {
1033 Py_DECREF(result);
1034 return Tkinter_Error(tkapp);
1035 }
1036 elem = FromObj(tkapp, tcl_elem);
1037 if (!elem) {
1038 Py_DECREF(result);
1039 return NULL;
1040 }
1041 PyTuple_SetItem(result, i, elem);
1042 }
1043 return result;
1044 }
1045
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001046 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001047 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +00001048 }
1049
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001050 if (value->typePtr == app->StringType) {
Martin v. Löwis6f29ff32003-04-16 20:34:55 +00001051#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
Martin v. Löwisffad6332002-11-26 09:28:05 +00001052 PyObject *result;
1053 int size;
1054 Tcl_UniChar *input;
1055 Py_UNICODE *output;
1056
1057 size = Tcl_GetCharLength(value);
1058 result = PyUnicode_FromUnicode(NULL, size);
1059 if (!result)
1060 return NULL;
1061 input = Tcl_GetUnicode(value);
1062 output = PyUnicode_AS_UNICODE(result);
1063 while (size--)
1064 *output++ = *input++;
1065 return result;
1066#else
1067 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1068 Tcl_GetCharLength(value));
1069#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +00001070 }
1071
1072 return newPyTclObject(value);
1073}
1074
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001075/* This mutex synchronizes inter-thread command calls. */
1076
1077TCL_DECLARE_MUTEX(call_mutex)
1078
1079typedef struct Tkapp_CallEvent {
1080 Tcl_Event ev; /* Must be first */
1081 TkappObject *self;
1082 PyObject *args;
1083 int flags;
1084 PyObject **res;
1085 PyObject **exc_type, **exc_value, **exc_tb;
1086 Tcl_Condition done;
1087} Tkapp_CallEvent;
1088
1089void
1090Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001091{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001092 int i;
1093 for (i = 0; i < objc; i++)
1094 Tcl_DecrRefCount(objv[i]);
1095 if (objv != objStore)
1096 ckfree(FREECAST objv);
1097}
Guido van Rossum18468821994-06-20 07:49:28 +00001098
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001099/* Convert Python objects to Tcl objects. This must happen in the
1100 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001101
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001102static Tcl_Obj**
1103Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1104{
1105 Tcl_Obj **objv = objStore;
Martin v. Löwis7d134952002-12-12 19:05:48 +00001106 int objc = 0, i;
Guido van Rossum212643f1998-04-29 16:22:14 +00001107 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +00001108 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001109
Guido van Rossum212643f1998-04-29 16:22:14 +00001110 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +00001111 objv[0] = AsObj(args);
1112 if (objv[0] == 0)
1113 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001114 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +00001115 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001116 }
1117 else {
Guido van Rossum632de272000-03-29 00:19:50 +00001118 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001119
Guido van Rossum632de272000-03-29 00:19:50 +00001120 if (objc > ARGSZ) {
1121 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1122 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001123 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +00001124 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +00001125 goto finally;
1126 }
1127 }
1128
Guido van Rossum632de272000-03-29 00:19:50 +00001129 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001130 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +00001131 if (v == Py_None) {
1132 objc = i;
1133 break;
1134 }
Guido van Rossum632de272000-03-29 00:19:50 +00001135 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +00001136 if (!objv[i]) {
1137 /* Reset objc, so it attempts to clear
1138 objects only up to i. */
1139 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +00001140 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001141 }
Guido van Rossum632de272000-03-29 00:19:50 +00001142 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001143 }
1144 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001145 *pobjc = objc;
1146 return objv;
1147finally:
1148 Tkapp_CallDeallocArgs(objv, objStore, objc);
1149 return NULL;
1150}
Guido van Rossum212643f1998-04-29 16:22:14 +00001151
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001152/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001153
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001154static PyObject*
1155Tkapp_CallResult(TkappObject *self)
1156{
1157 PyObject *res = NULL;
1158 if(self->wantobjects) {
1159 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001160 /* Not sure whether the IncrRef is necessary, but something
1161 may overwrite the interpreter result while we are
1162 converting it. */
1163 Tcl_IncrRefCount(value);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001164 res = FromObj((PyObject*)self, value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001165 Tcl_DecrRefCount(value);
1166 } else {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001167 const char *s = Tcl_GetStringResult(self->interp);
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001168 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001169
Guido van Rossum990f5c62000-05-04 15:07:16 +00001170 /* If the result contains any bytes with the top bit set,
1171 it's UTF-8 and we should decode it to Unicode */
1172 while (*p != '\0') {
1173 if (*p & 0x80)
1174 break;
1175 p++;
1176 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001177
Guido van Rossum990f5c62000-05-04 15:07:16 +00001178 if (*p == '\0')
1179 res = PyString_FromStringAndSize(s, (int)(p-s));
1180 else {
1181 /* Convert UTF-8 to Unicode string */
1182 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +00001183 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
1184 if (res == NULL) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001185 PyErr_Clear();
1186 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +00001187 }
Guido van Rossum990f5c62000-05-04 15:07:16 +00001188 }
1189 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001190 return res;
1191}
Guido van Rossum632de272000-03-29 00:19:50 +00001192
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001193/* Tkapp_CallProc is the event procedure that is executed in the context of
1194 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1195 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001196
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001197static int
1198Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1199{
1200 Tcl_Obj *objStore[ARGSZ];
1201 Tcl_Obj **objv;
1202 int objc;
1203 int i;
1204 ENTER_PYTHON
1205 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1206 if (!objv) {
1207 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1208 *(e->res) = NULL;
1209 }
1210 LEAVE_PYTHON
1211 if (!objv)
1212 goto done;
1213 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1214 ENTER_PYTHON
1215 if (i == TCL_ERROR) {
1216 *(e->res) = NULL;
1217 *(e->exc_type) = NULL;
1218 *(e->exc_tb) = NULL;
1219 *(e->exc_value) = PyObject_CallFunction(
1220 Tkinter_TclError, "s",
1221 Tcl_GetStringResult(e->self->interp));
1222 }
1223 else {
1224 *(e->res) = Tkapp_CallResult(e->self);
1225 }
1226 LEAVE_PYTHON
1227 done:
1228 /* Wake up calling thread. */
1229 Tcl_MutexLock(&call_mutex);
1230 Tcl_ConditionNotify(&e->done);
1231 Tcl_MutexUnlock(&call_mutex);
1232 return 1;
1233}
1234
1235/* This is the main entry point for calling a Tcl command.
1236 It supports three cases, with regard to threading:
1237 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1238 the context of the calling thread.
1239 2. Tcl is threaded, caller of the command is in the interpreter thread:
1240 Execute the command in the calling thread. Since the Tcl lock will
1241 not be used, we can merge that with case 1.
1242 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1243 the interpreter thread. Allocation of Tcl objects needs to occur in the
1244 interpreter thread, so we ship the PyObject* args to the target thread,
1245 and perform processing there. */
1246
1247static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001248Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001249{
1250 Tcl_Obj *objStore[ARGSZ];
1251 Tcl_Obj **objv = NULL;
1252 int objc, i;
1253 PyObject *res = NULL;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001254 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001255 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
1256 int flags = TCL_EVAL_DIRECT;
1257
Guido van Rossum992d4a32007-07-11 13:09:30 +00001258 /* If args is a single tuple, replace with contents of tuple */
1259 if (1 == PyTuple_Size(args)){
1260 PyObject* item = PyTuple_GetItem(args, 0);
1261 if (PyTuple_Check(item))
1262 args = item;
1263 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001264#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001265 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1266 /* We cannot call the command directly. Instead, we must
1267 marshal the parameters to the interpreter thread. */
1268 Tkapp_CallEvent *ev;
1269 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001270 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001271 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001272 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1273 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1274 ev->self = self;
1275 ev->args = args;
1276 ev->res = &res;
1277 ev->exc_type = &exc_type;
1278 ev->exc_value = &exc_value;
1279 ev->exc_tb = &exc_tb;
1280 ev->done = (Tcl_Condition)0;
1281
1282 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &call_mutex);
1283
1284 if (res == NULL) {
1285 if (exc_type)
1286 PyErr_Restore(exc_type, exc_value, exc_tb);
1287 else
1288 PyErr_SetObject(Tkinter_TclError, exc_value);
1289 }
1290 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001291 else
1292#endif
1293 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001294
1295 objv = Tkapp_CallArgs(args, objStore, &objc);
1296 if (!objv)
1297 return NULL;
1298
1299 ENTER_TCL
1300
1301 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1302
1303 ENTER_OVERLAP
1304
1305 if (i == TCL_ERROR)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001306 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001307 else
1308 res = Tkapp_CallResult(self);
1309
1310 LEAVE_OVERLAP_TCL
1311
1312 Tkapp_CallDeallocArgs(objv, objStore, objc);
1313 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001314 return res;
1315}
1316
1317
1318static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001319Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001320{
Guido van Rossum212643f1998-04-29 16:22:14 +00001321 /* Could do the same here as for Tkapp_Call(), but this is not used
1322 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1323 way for the user to do what all its Global* variants do (save and
1324 reset the scope pointer, call the local version, restore the saved
1325 scope pointer). */
1326
Guido van Rossum62320c91998-06-15 04:36:09 +00001327 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001328 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001329
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001330 CHECK_TCL_APPARTMENT;
1331
Guido van Rossum62320c91998-06-15 04:36:09 +00001332 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001333 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001334 int err;
1335 ENTER_TCL
1336 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001337 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001338 if (err == TCL_ERROR)
1339 res = Tkinter_Error(self);
1340 else
1341 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001342 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001343 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001344 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001345
1346 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001347}
1348
1349static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001350Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001351{
Barry Warsawfa701a81997-01-16 00:15:11 +00001352 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001353 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001354 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001355
Guido van Rossum43713e52000-02-29 13:59:29 +00001356 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001357 return NULL;
1358
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001359 CHECK_TCL_APPARTMENT;
1360
Guido van Rossum00d93061998-05-28 23:06:38 +00001361 ENTER_TCL
1362 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001363 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001364 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001365 res = Tkinter_Error(self);
1366 else
1367 res = PyString_FromString(Tkapp_Result(self));
1368 LEAVE_OVERLAP_TCL
1369 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001370}
1371
1372static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001373Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001374{
Barry Warsawfa701a81997-01-16 00:15:11 +00001375 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001376 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001377 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001378
Guido van Rossum43713e52000-02-29 13:59:29 +00001379 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001380 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001381
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001382 CHECK_TCL_APPARTMENT;
1383
Guido van Rossum00d93061998-05-28 23:06:38 +00001384 ENTER_TCL
1385 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001386 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001387 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001388 res = Tkinter_Error(self);
1389 else
1390 res = PyString_FromString(Tkapp_Result(self));
1391 LEAVE_OVERLAP_TCL
1392 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001393}
1394
1395static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001396Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001397{
Barry Warsawfa701a81997-01-16 00:15:11 +00001398 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001399 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001400 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001401
Guido van Rossum43713e52000-02-29 13:59:29 +00001402 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001403 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001404
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001405 CHECK_TCL_APPARTMENT;
1406
Guido van Rossum00d93061998-05-28 23:06:38 +00001407 ENTER_TCL
1408 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001409 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001410 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001411 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001412
Guido van Rossum62320c91998-06-15 04:36:09 +00001413 else
1414 res = PyString_FromString(Tkapp_Result(self));
1415 LEAVE_OVERLAP_TCL
1416 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001417}
1418
1419static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001420Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001421{
Barry Warsawfa701a81997-01-16 00:15:11 +00001422 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001423 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001424 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001425
Guido van Rossum35d43371997-08-02 00:09:09 +00001426 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001427 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001428
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001429 CHECK_TCL_APPARTMENT;
1430
Guido van Rossum00d93061998-05-28 23:06:38 +00001431 ENTER_TCL
1432 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001433 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001434 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001435 res = Tkinter_Error(self);
1436 else
1437 res = PyString_FromString(Tkapp_Result(self));
1438 LEAVE_OVERLAP_TCL
1439 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001440}
1441
1442static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001443Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001444{
Barry Warsawfa701a81997-01-16 00:15:11 +00001445 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001446
Guido van Rossum43713e52000-02-29 13:59:29 +00001447 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001448 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001449 CHECK_TCL_APPARTMENT;
1450
Guido van Rossum00d93061998-05-28 23:06:38 +00001451 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001452 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001453 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001454
Barry Warsawfa701a81997-01-16 00:15:11 +00001455 Py_INCREF(Py_None);
1456 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001457}
1458
Barry Warsawfa701a81997-01-16 00:15:11 +00001459
1460
Guido van Rossum18468821994-06-20 07:49:28 +00001461/** Tcl Variable **/
1462
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001463TCL_DECLARE_MUTEX(var_mutex)
1464
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001465typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001466typedef struct VarEvent {
1467 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001468 PyObject *self;
1469 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001470 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001471 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001472 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001473 PyObject **exc_type;
1474 PyObject **exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001475 Tcl_Condition cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001476} VarEvent;
1477
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001478static int
1479varname_converter(PyObject *in, void *_out)
1480{
1481 char **out = (char**)_out;
1482 if (PyString_Check(in)) {
1483 *out = PyString_AsString(in);
1484 return 1;
1485 }
1486 if (PyTclObject_Check(in)) {
1487 *out = PyTclObject_TclString(in);
1488 return 1;
1489 }
1490 /* XXX: Should give diagnostics. */
1491 return 0;
1492}
1493
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001494void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001495var_perform(VarEvent *ev)
1496{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001497 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1498 if (!*(ev->res)) {
1499 PyObject *exc, *val, *tb;
1500 PyErr_Fetch(&exc, &val, &tb);
1501 PyErr_NormalizeException(&exc, &val, &tb);
1502 *(ev->exc_type) = exc;
1503 *(ev->exc_val) = val;
1504 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001505 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001506
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001507}
1508
1509static int
1510var_proc(VarEvent* ev, int flags)
1511{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001512 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001513 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001514 Tcl_MutexLock(&var_mutex);
1515 Tcl_ConditionNotify(&ev->cond);
1516 Tcl_MutexUnlock(&var_mutex);
1517 LEAVE_PYTHON
1518 return 1;
1519}
1520
1521static PyObject*
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001522var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001523{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001524 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisa9656492003-03-30 08:44:58 +00001525#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001526 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001527 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001528 VarEvent *ev;
1529 PyObject *res, *exc_type, *exc_val;
1530
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001531 /* The current thread is not the interpreter thread. Marshal
1532 the call to the interpreter thread, then wait for
1533 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001534 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001535 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001536
1537 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1538
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001539 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001540 ev->args = args;
1541 ev->flags = flags;
1542 ev->func = func;
1543 ev->res = &res;
1544 ev->exc_type = &exc_type;
1545 ev->exc_val = &exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001546 ev->cond = NULL;
1547 ev->ev.proc = (Tcl_EventProc*)var_proc;
1548 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001549 if (!res) {
1550 PyErr_SetObject(exc_type, exc_val);
1551 Py_DECREF(exc_type);
1552 Py_DECREF(exc_val);
1553 return NULL;
1554 }
1555 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001556 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001557#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001558 /* Tcl is not threaded, or this is the interpreter thread. */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001559 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001560}
1561
Guido van Rossum18468821994-06-20 07:49:28 +00001562static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001563SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001564{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001565 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001566 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001567 PyObject *res = NULL;
1568 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001569
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001570 if (PyArg_ParseTuple(args, "O&O:setvar",
1571 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001572 /* XXX Acquire tcl lock??? */
1573 newval = AsObj(newValue);
1574 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001575 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001576 ENTER_TCL
1577 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1578 newval, flags);
1579 ENTER_OVERLAP
1580 if (!ok)
1581 Tkinter_Error(self);
1582 else {
1583 res = Py_None;
1584 Py_INCREF(res);
1585 }
1586 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001587 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001588 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001589 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001590 if (PyArg_ParseTuple(args, "ssO:setvar",
1591 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001592 /* XXX must hold tcl lock already??? */
1593 newval = AsObj(newValue);
1594 ENTER_TCL
1595 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1596 ENTER_OVERLAP
1597 if (!ok)
1598 Tkinter_Error(self);
1599 else {
1600 res = Py_None;
1601 Py_INCREF(res);
1602 }
1603 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001604 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001605 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001606 return NULL;
1607 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001608 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001609 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001610}
1611
1612static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001613Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001614{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001615 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001616}
1617
1618static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001619Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001620{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001621 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001622}
1623
Barry Warsawfa701a81997-01-16 00:15:11 +00001624
1625
Guido van Rossum18468821994-06-20 07:49:28 +00001626static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001627GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001628{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001629 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001630 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001631 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001632
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001633 if (!PyArg_ParseTuple(args, "O&|s:getvar",
1634 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001635 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001636
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001637 ENTER_TCL
1638 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1639 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001640 if (tres == NULL) {
1641 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1642 } else {
1643 if (((TkappObject*)self)->wantobjects) {
1644 res = FromObj(self, tres);
1645 }
1646 else {
1647 res = PyString_FromString(Tcl_GetString(tres));
1648 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001649 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001650 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001651 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001652}
1653
1654static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001655Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001656{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001657 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001658}
1659
1660static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001661Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001662{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001663 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001664}
1665
Barry Warsawfa701a81997-01-16 00:15:11 +00001666
1667
Guido van Rossum18468821994-06-20 07:49:28 +00001668static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001669UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001670{
Guido van Rossum35d43371997-08-02 00:09:09 +00001671 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001672 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001673 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001674
Guido van Rossum43713e52000-02-29 13:59:29 +00001675 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001676 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001677
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001678 ENTER_TCL
1679 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1680 ENTER_OVERLAP
1681 if (code == TCL_ERROR)
1682 res = Tkinter_Error(self);
1683 else {
1684 Py_INCREF(Py_None);
1685 res = Py_None;
1686 }
1687 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001688 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001689}
1690
1691static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001692Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001693{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001694 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001695}
1696
1697static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001698Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001699{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001700 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001701}
1702
Barry Warsawfa701a81997-01-16 00:15:11 +00001703
1704
Guido van Rossum18468821994-06-20 07:49:28 +00001705/** Tcl to Python **/
1706
1707static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001708Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001709{
Barry Warsawfa701a81997-01-16 00:15:11 +00001710 char *s;
1711 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001712
Martin v. Löwisffad6332002-11-26 09:28:05 +00001713 if (PyTuple_Size(args) == 1) {
1714 PyObject* o = PyTuple_GetItem(args, 0);
1715 if (PyInt_Check(o)) {
1716 Py_INCREF(o);
1717 return o;
1718 }
1719 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001720 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001721 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001722 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001723 return Tkinter_Error(self);
1724 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001725}
1726
1727static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001728Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001729{
Barry Warsawfa701a81997-01-16 00:15:11 +00001730 char *s;
1731 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001732
Martin v. Löwisffad6332002-11-26 09:28:05 +00001733 if (PyTuple_Size(args) == 1) {
1734 PyObject *o = PyTuple_GetItem(args, 0);
1735 if (PyFloat_Check(o)) {
1736 Py_INCREF(o);
1737 return o;
1738 }
1739 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001740 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001741 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001742 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001743 return Tkinter_Error(self);
1744 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001745}
1746
1747static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001748Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001749{
Barry Warsawfa701a81997-01-16 00:15:11 +00001750 char *s;
1751 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001752
Martin v. Löwisffad6332002-11-26 09:28:05 +00001753 if (PyTuple_Size(args) == 1) {
1754 PyObject *o = PyTuple_GetItem(args, 0);
1755 if (PyInt_Check(o)) {
1756 Py_INCREF(o);
1757 return o;
1758 }
1759 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001760 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001761 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001762 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1763 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001764 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001765}
1766
1767static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001768Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001769{
Barry Warsawfa701a81997-01-16 00:15:11 +00001770 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001771 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001772 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001773
Guido van Rossum43713e52000-02-29 13:59:29 +00001774 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001775 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001776
1777 CHECK_TCL_APPARTMENT;
1778
Guido van Rossum00d93061998-05-28 23:06:38 +00001779 ENTER_TCL
1780 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001781 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001782 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001783 res = Tkinter_Error(self);
1784 else
1785 res = Py_BuildValue("s", Tkapp_Result(self));
1786 LEAVE_OVERLAP_TCL
1787 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001788}
1789
1790static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001791Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001792{
Barry Warsawfa701a81997-01-16 00:15:11 +00001793 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001794 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001795 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001796 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001797
Guido van Rossum43713e52000-02-29 13:59:29 +00001798 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001799 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001800
1801 CHECK_TCL_APPARTMENT;
1802
Guido van Rossum00d93061998-05-28 23:06:38 +00001803 ENTER_TCL
1804 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001805 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001806 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001807 res = Tkinter_Error(self);
1808 else
1809 res = Py_BuildValue("l", v);
1810 LEAVE_OVERLAP_TCL
1811 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001812}
1813
1814static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001815Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001816{
Barry Warsawfa701a81997-01-16 00:15:11 +00001817 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001818 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001819 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001820 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001821
Guido van Rossum43713e52000-02-29 13:59:29 +00001822 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001823 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001824 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001825 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001826 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001827 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001828 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001829 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001830 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001831 res = Tkinter_Error(self);
1832 else
1833 res = Py_BuildValue("d", v);
1834 LEAVE_OVERLAP_TCL
1835 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001836}
1837
1838static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001839Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001840{
Barry Warsawfa701a81997-01-16 00:15:11 +00001841 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001842 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001843 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001844 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001845
Guido van Rossum43713e52000-02-29 13:59:29 +00001846 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001847 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001848 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001849 ENTER_TCL
1850 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001851 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001852 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001853 res = Tkinter_Error(self);
1854 else
1855 res = Py_BuildValue("i", v);
1856 LEAVE_OVERLAP_TCL
1857 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001858}
1859
Barry Warsawfa701a81997-01-16 00:15:11 +00001860
1861
Guido van Rossum18468821994-06-20 07:49:28 +00001862static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001863Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001864{
Barry Warsawfa701a81997-01-16 00:15:11 +00001865 char *list;
1866 int argc;
1867 char **argv;
1868 PyObject *v;
1869 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001870
Martin v. Löwisffad6332002-11-26 09:28:05 +00001871 if (PyTuple_Size(args) == 1) {
1872 v = PyTuple_GetItem(args, 0);
1873 if (PyTuple_Check(v)) {
1874 Py_INCREF(v);
1875 return v;
1876 }
1877 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001878 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001879 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001880
Neal Norwitzd1c55102003-05-29 00:17:03 +00001881 if (Tcl_SplitList(Tkapp_Interp(self), list,
1882 &argc, &argv) == TCL_ERROR) {
1883 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001884 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001885 }
Guido van Rossum18468821994-06-20 07:49:28 +00001886
Barry Warsawfa701a81997-01-16 00:15:11 +00001887 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001888 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001889
Barry Warsawfa701a81997-01-16 00:15:11 +00001890 for (i = 0; i < argc; i++) {
1891 PyObject *s = PyString_FromString(argv[i]);
1892 if (!s || PyTuple_SetItem(v, i, s)) {
1893 Py_DECREF(v);
1894 v = NULL;
1895 goto finally;
1896 }
1897 }
Guido van Rossum18468821994-06-20 07:49:28 +00001898
Barry Warsawfa701a81997-01-16 00:15:11 +00001899 finally:
1900 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001901 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001902 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001903}
1904
1905static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001906Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001907{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001908 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001909 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001910
Martin v. Löwisffad6332002-11-26 09:28:05 +00001911 if (PyTuple_Size(args) == 1) {
1912 PyObject* o = PyTuple_GetItem(args, 0);
1913 if (PyTuple_Check(o)) {
1914 o = SplitObj(o);
1915 return o;
1916 }
1917 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001918 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001919 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00001920 v = Split(list);
1921 PyMem_Free(list);
1922 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001923}
1924
1925static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001926Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001927{
Barry Warsawfa701a81997-01-16 00:15:11 +00001928 char *s = Merge(args);
1929 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001930
Barry Warsawfa701a81997-01-16 00:15:11 +00001931 if (s) {
1932 res = PyString_FromString(s);
1933 ckfree(s);
1934 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001935
1936 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001937}
1938
Barry Warsawfa701a81997-01-16 00:15:11 +00001939
1940
Guido van Rossum18468821994-06-20 07:49:28 +00001941/** Tcl Command **/
1942
Guido van Rossum00d93061998-05-28 23:06:38 +00001943/* Client data struct */
1944typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001945 PyObject *self;
1946 PyObject *func;
1947} PythonCmd_ClientData;
1948
1949static int
Fred Drake509d79a2000-07-08 04:04:38 +00001950PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001951{
1952 errorInCmd = 1;
1953 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1954 LEAVE_PYTHON
1955 return TCL_ERROR;
1956}
1957
Guido van Rossum18468821994-06-20 07:49:28 +00001958/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001959 * function or method.
1960 */
Guido van Rossum18468821994-06-20 07:49:28 +00001961static int
Fred Drake509d79a2000-07-08 04:04:38 +00001962PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001963{
Guido van Rossum00d93061998-05-28 23:06:38 +00001964 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001965 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001966 int i, rv;
1967 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001968
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001969 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001970
Barry Warsawfa701a81997-01-16 00:15:11 +00001971 /* TBD: no error checking here since we know, via the
1972 * Tkapp_CreateCommand() that the client data is a two-tuple
1973 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001974 self = data->self;
1975 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001976
Barry Warsawfa701a81997-01-16 00:15:11 +00001977 /* Create argument list (argv1, ..., argvN) */
1978 if (!(arg = PyTuple_New(argc - 1)))
1979 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001980
Barry Warsawfa701a81997-01-16 00:15:11 +00001981 for (i = 0; i < (argc - 1); i++) {
1982 PyObject *s = PyString_FromString(argv[i + 1]);
1983 if (!s || PyTuple_SetItem(arg, i, s)) {
1984 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001985 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001986 }
1987 }
1988 res = PyEval_CallObject(func, arg);
1989 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001990
Barry Warsawfa701a81997-01-16 00:15:11 +00001991 if (res == NULL)
1992 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001993
Barry Warsawfa701a81997-01-16 00:15:11 +00001994 if (!(tmp = PyList_New(0))) {
1995 Py_DECREF(res);
1996 return PythonCmd_Error(interp);
1997 }
1998
Guido van Rossum2834b972000-10-06 16:58:26 +00001999 s = AsString(res, tmp);
2000 if (s == NULL) {
2001 rv = PythonCmd_Error(interp);
2002 }
2003 else {
2004 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
2005 rv = TCL_OK;
2006 }
2007
Barry Warsawfa701a81997-01-16 00:15:11 +00002008 Py_DECREF(res);
2009 Py_DECREF(tmp);
2010
Guido van Rossum00d93061998-05-28 23:06:38 +00002011 LEAVE_PYTHON
2012
Guido van Rossum2834b972000-10-06 16:58:26 +00002013 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002014}
2015
2016static void
Fred Drake509d79a2000-07-08 04:04:38 +00002017PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002018{
Guido van Rossum00d93061998-05-28 23:06:38 +00002019 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2020
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002021 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002022 Py_XDECREF(data->self);
2023 Py_XDECREF(data->func);
2024 PyMem_DEL(data);
2025 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002026}
2027
Barry Warsawfa701a81997-01-16 00:15:11 +00002028
2029
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002030
2031TCL_DECLARE_MUTEX(command_mutex)
2032
2033typedef struct CommandEvent{
2034 Tcl_Event ev;
2035 Tcl_Interp* interp;
2036 char *name;
2037 int create;
2038 int *status;
2039 ClientData *data;
2040 Tcl_Condition done;
2041} CommandEvent;
2042
2043static int
2044Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002045{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002046 if (ev->create)
2047 *ev->status = Tcl_CreateCommand(
2048 ev->interp, ev->name, PythonCmd,
2049 ev->data, PythonCmdDelete) == NULL;
2050 else
2051 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2052 Tcl_MutexLock(&command_mutex);
2053 Tcl_ConditionNotify(&ev->done);
2054 Tcl_MutexUnlock(&command_mutex);
2055 return 1;
2056}
2057
2058static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002059Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002060{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002061 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002062 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002063 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002064 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002065 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002066
Guido van Rossum43713e52000-02-29 13:59:29 +00002067 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002068 return NULL;
2069 if (!PyCallable_Check(func)) {
2070 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002071 return NULL;
2072 }
Guido van Rossum18468821994-06-20 07:49:28 +00002073
Martin v. Löwisa9656492003-03-30 08:44:58 +00002074#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002075 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002076 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002077 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002078#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002079
Guido van Rossum00d93061998-05-28 23:06:38 +00002080 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002081 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002082 return PyErr_NoMemory();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002083 Py_INCREF(self);
2084 Py_INCREF(func);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002085 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002086 data->func = func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002087
2088 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2089 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2090 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2091 ev->interp = self->interp;
2092 ev->create = 1;
2093 ev->name = cmdName;
2094 ev->data = (ClientData)data;
2095 ev->status = &err;
2096 ev->done = NULL;
2097 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
2098 }
2099 else {
2100 ENTER_TCL
2101 err = Tcl_CreateCommand(
2102 Tkapp_Interp(self), cmdName, PythonCmd,
2103 (ClientData)data, PythonCmdDelete) == NULL;
2104 LEAVE_TCL
2105 }
2106 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002107 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002108 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002109 return NULL;
2110 }
Guido van Rossum18468821994-06-20 07:49:28 +00002111
Barry Warsawfa701a81997-01-16 00:15:11 +00002112 Py_INCREF(Py_None);
2113 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002114}
2115
Barry Warsawfa701a81997-01-16 00:15:11 +00002116
2117
Guido van Rossum18468821994-06-20 07:49:28 +00002118static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002119Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002120{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002121 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002122 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002123 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002124
Guido van Rossum43713e52000-02-29 13:59:29 +00002125 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002126 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002127 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2128 CommandEvent *ev;
2129 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2130 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2131 ev->interp = self->interp;
2132 ev->create = 0;
2133 ev->name = cmdName;
2134 ev->status = &err;
2135 ev->done = NULL;
2136 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done,
2137 &command_mutex);
2138 }
2139 else {
2140 ENTER_TCL
2141 err = Tcl_DeleteCommand(self->interp, cmdName);
2142 LEAVE_TCL
2143 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002144 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002145 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2146 return NULL;
2147 }
2148 Py_INCREF(Py_None);
2149 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002150}
2151
Barry Warsawfa701a81997-01-16 00:15:11 +00002152
2153
Guido van Rossum00d93061998-05-28 23:06:38 +00002154#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002155/** File Handler **/
2156
Guido van Rossum00d93061998-05-28 23:06:38 +00002157typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002158 PyObject *func;
2159 PyObject *file;
2160 int id;
2161 struct _fhcdata *next;
2162} FileHandler_ClientData;
2163
2164static FileHandler_ClientData *HeadFHCD;
2165
2166static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002167NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002168{
2169 FileHandler_ClientData *p;
2170 p = PyMem_NEW(FileHandler_ClientData, 1);
2171 if (p != NULL) {
2172 Py_XINCREF(func);
2173 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002174 p->func = func;
2175 p->file = file;
2176 p->id = id;
2177 p->next = HeadFHCD;
2178 HeadFHCD = p;
2179 }
2180 return p;
2181}
2182
2183static void
Fred Drake509d79a2000-07-08 04:04:38 +00002184DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002185{
2186 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002187
2188 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002189 while ((p = *pp) != NULL) {
2190 if (p->id == id) {
2191 *pp = p->next;
2192 Py_XDECREF(p->func);
2193 Py_XDECREF(p->file);
2194 PyMem_DEL(p);
2195 }
2196 else
2197 pp = &p->next;
2198 }
2199}
2200
Guido van Rossuma597dde1995-01-10 20:56:29 +00002201static void
Fred Drake509d79a2000-07-08 04:04:38 +00002202FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002203{
Guido van Rossum00d93061998-05-28 23:06:38 +00002204 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002205 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002206
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002207 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002208 func = data->func;
2209 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002210
Barry Warsawfa701a81997-01-16 00:15:11 +00002211 arg = Py_BuildValue("(Oi)", file, (long) mask);
2212 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002213 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002214
2215 if (res == NULL) {
2216 errorInCmd = 1;
2217 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2218 }
2219 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002220 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002221}
2222
Guido van Rossum18468821994-06-20 07:49:28 +00002223static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002224Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2225 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002226{
Guido van Rossum00d93061998-05-28 23:06:38 +00002227 FileHandler_ClientData *data;
2228 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002229 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002230
Guido van Rossum2834b972000-10-06 16:58:26 +00002231 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2232 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002233 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002234
Martin v. Löwisa9656492003-03-30 08:44:58 +00002235#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002236 if (!self && !tcl_lock) {
2237 /* We don't have the Tcl lock since Tcl is threaded. */
2238 PyErr_SetString(PyExc_RuntimeError,
2239 "_tkinter.createfilehandler not supported "
2240 "for threaded Tcl");
2241 return NULL;
2242 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002243#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002244
2245 if (self) {
2246 CHECK_TCL_APPARTMENT;
2247 }
2248
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002249 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002250 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002251 return NULL;
2252 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002253 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002254 return NULL;
2255 }
2256
Guido van Rossuma80649b2000-03-28 20:07:05 +00002257 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002258 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002259 return NULL;
2260
Barry Warsawfa701a81997-01-16 00:15:11 +00002261 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002262 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002263 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002264 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002265 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002266 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002267}
2268
2269static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002270Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002271{
Barry Warsawfa701a81997-01-16 00:15:11 +00002272 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002273 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002274
Guido van Rossum43713e52000-02-29 13:59:29 +00002275 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002276 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002277
Martin v. Löwisa9656492003-03-30 08:44:58 +00002278#ifdef WITH_THREAD
Neal Norwitz12e22172003-03-03 21:16:39 +00002279 if (!self && !tcl_lock) {
2280 /* We don't have the Tcl lock since Tcl is threaded. */
2281 PyErr_SetString(PyExc_RuntimeError,
2282 "_tkinter.deletefilehandler not supported "
2283 "for threaded Tcl");
2284 return NULL;
2285 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002286#endif
Neal Norwitz12e22172003-03-03 21:16:39 +00002287
2288 if (self) {
2289 CHECK_TCL_APPARTMENT;
2290 }
2291
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002292 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002293 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002294 return NULL;
2295
Guido van Rossuma80649b2000-03-28 20:07:05 +00002296 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002297
Barry Warsawfa701a81997-01-16 00:15:11 +00002298 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002299 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002300 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002301 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002302 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002303 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002304}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002305#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002306
Barry Warsawfa701a81997-01-16 00:15:11 +00002307
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002308/**** Tktt Object (timer token) ****/
2309
Jeremy Hylton938ace62002-07-17 16:30:39 +00002310static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002311
Guido van Rossum00d93061998-05-28 23:06:38 +00002312typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002313 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002314 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002315 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002316} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002317
2318static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002319Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002320{
Barry Warsawfa701a81997-01-16 00:15:11 +00002321 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002322 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002323
Guido van Rossum43713e52000-02-29 13:59:29 +00002324 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002325 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002326 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002327 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002328 v->token = NULL;
2329 }
2330 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002331 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002332 Py_DECREF(func);
2333 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002334 }
2335 Py_INCREF(Py_None);
2336 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002337}
2338
2339static PyMethodDef Tktt_methods[] =
2340{
Neal Norwitzb0493252002-03-31 14:44:22 +00002341 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002342 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002343};
2344
2345static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002346Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002347{
Barry Warsawfa701a81997-01-16 00:15:11 +00002348 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002349
Guido van Rossumb18618d2000-05-03 23:44:39 +00002350 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002351 if (v == NULL)
2352 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002353
Guido van Rossum00d93061998-05-28 23:06:38 +00002354 Py_INCREF(func);
2355 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002356 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002357
2358 /* Extra reference, deleted when called or when handler is deleted */
2359 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002360 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002361}
2362
2363static void
Fred Drake509d79a2000-07-08 04:04:38 +00002364Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002365{
Guido van Rossum00d93061998-05-28 23:06:38 +00002366 TkttObject *v = (TkttObject *)self;
2367 PyObject *func = v->func;
2368
2369 Py_XDECREF(func);
2370
Guido van Rossumb18618d2000-05-03 23:44:39 +00002371 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002372}
2373
Guido van Rossum597ac201998-05-12 14:36:19 +00002374static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002375Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002376{
Barry Warsawfa701a81997-01-16 00:15:11 +00002377 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002378 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002379
Tim Peters885d4572001-11-28 20:27:42 +00002380 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002381 v->func == NULL ? ", handler deleted" : "");
Walter Dörwald1ab83302007-05-18 17:15:44 +00002382 return PyUnicode_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002383}
2384
2385static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002386Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002387{
Barry Warsawfa701a81997-01-16 00:15:11 +00002388 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002389}
2390
2391static PyTypeObject Tktt_Type =
2392{
Guido van Rossum35d43371997-08-02 00:09:09 +00002393 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002394 0, /*ob_size */
2395 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002396 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002397 0, /*tp_itemsize */
2398 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002399 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00002400 Tktt_GetAttr, /*tp_getattr */
2401 0, /*tp_setattr */
2402 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00002403 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002404 0, /*tp_as_number */
2405 0, /*tp_as_sequence */
2406 0, /*tp_as_mapping */
2407 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002408};
2409
Barry Warsawfa701a81997-01-16 00:15:11 +00002410
2411
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002412/** Timer Handler **/
2413
2414static void
Fred Drake509d79a2000-07-08 04:04:38 +00002415TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002416{
Guido van Rossum00d93061998-05-28 23:06:38 +00002417 TkttObject *v = (TkttObject *)clientData;
2418 PyObject *func = v->func;
2419 PyObject *res;
2420
2421 if (func == NULL)
2422 return;
2423
2424 v->func = NULL;
2425
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002426 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002427
2428 res = PyEval_CallObject(func, NULL);
2429 Py_DECREF(func);
2430 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002431
Barry Warsawfa701a81997-01-16 00:15:11 +00002432 if (res == NULL) {
2433 errorInCmd = 1;
2434 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2435 }
2436 else
2437 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002438
2439 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002440}
2441
2442static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002443Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002444{
Barry Warsawfa701a81997-01-16 00:15:11 +00002445 int milliseconds;
2446 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002447 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002448
Guido van Rossum2834b972000-10-06 16:58:26 +00002449 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2450 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002451 return NULL;
2452 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002453 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002454 return NULL;
2455 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002456
Martin v. Löwisa9656492003-03-30 08:44:58 +00002457#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002458 if (!self && !tcl_lock) {
2459 /* We don't have the Tcl lock since Tcl is threaded. */
2460 PyErr_SetString(PyExc_RuntimeError,
2461 "_tkinter.createtimerhandler not supported "
2462 "for threaded Tcl");
2463 return NULL;
2464 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002465#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002466
2467 if (self) {
2468 CHECK_TCL_APPARTMENT;
2469 }
2470
Guido van Rossum00d93061998-05-28 23:06:38 +00002471 v = Tktt_New(func);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002472 if (v) {
2473 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2474 (ClientData)v);
2475 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002476
Guido van Rossum00d93061998-05-28 23:06:38 +00002477 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002478}
2479
Barry Warsawfa701a81997-01-16 00:15:11 +00002480
Guido van Rossum18468821994-06-20 07:49:28 +00002481/** Event Loop **/
2482
Guido van Rossum18468821994-06-20 07:49:28 +00002483static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002484Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002485{
Barry Warsawfa701a81997-01-16 00:15:11 +00002486 int threshold = 0;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002487 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002488#ifdef WITH_THREAD
2489 PyThreadState *tstate = PyThreadState_Get();
2490#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002491
Guido van Rossum43713e52000-02-29 13:59:29 +00002492 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002493 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002494
Martin v. Löwisa9656492003-03-30 08:44:58 +00002495#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002496 if (!self && !tcl_lock) {
2497 /* We don't have the Tcl lock since Tcl is threaded. */
2498 PyErr_SetString(PyExc_RuntimeError,
2499 "_tkinter.mainloop not supported "
2500 "for threaded Tcl");
2501 return NULL;
2502 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002503#endif
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002504
2505 if (self) {
2506 CHECK_TCL_APPARTMENT;
2507 self->dispatching = 1;
2508 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002509
Barry Warsawfa701a81997-01-16 00:15:11 +00002510 quitMainLoop = 0;
2511 while (Tk_GetNumMainWindows() > threshold &&
2512 !quitMainLoop &&
2513 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002514 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002515 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002516
2517#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002518 if (self && self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002519 /* Allow other Python threads to run. */
2520 ENTER_TCL
2521 result = Tcl_DoOneEvent(0);
2522 LEAVE_TCL
2523 }
2524 else {
2525 Py_BEGIN_ALLOW_THREADS
2526 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2527 tcl_tstate = tstate;
2528 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2529 tcl_tstate = NULL;
2530 if(tcl_lock)PyThread_release_lock(tcl_lock);
2531 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002532 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002533 Py_END_ALLOW_THREADS
2534 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002535#else
2536 result = Tcl_DoOneEvent(0);
2537#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002538
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002539 if (PyErr_CheckSignals() != 0) {
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002540 if (self)
2541 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002542 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002543 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002544 if (result < 0)
2545 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002546 }
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002547 if (self)
2548 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002549 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002550
Barry Warsawfa701a81997-01-16 00:15:11 +00002551 if (errorInCmd) {
2552 errorInCmd = 0;
2553 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2554 excInCmd = valInCmd = trbInCmd = NULL;
2555 return NULL;
2556 }
2557 Py_INCREF(Py_None);
2558 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002559}
2560
2561static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002562Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002563{
Guido van Rossum35d43371997-08-02 00:09:09 +00002564 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002565 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002566
Guido van Rossum43713e52000-02-29 13:59:29 +00002567 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002568 return NULL;
2569
Guido van Rossum00d93061998-05-28 23:06:38 +00002570 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002571 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002572 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002573 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002574}
2575
2576static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002577Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002578{
2579
Guido van Rossum43713e52000-02-29 13:59:29 +00002580 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002581 return NULL;
2582
2583 quitMainLoop = 1;
2584 Py_INCREF(Py_None);
2585 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002586}
2587
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002588static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002589Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002590{
2591
Guido van Rossum43713e52000-02-29 13:59:29 +00002592 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002593 return NULL;
2594
2595 return PyInt_FromLong((long)Tkapp_Interp(self));
2596}
2597
David Aschere2b4b322004-02-18 05:59:53 +00002598static PyObject *
2599Tkapp_TkInit(PyObject *self, PyObject *args)
2600{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002601 static int has_failed;
David Aschere2b4b322004-02-18 05:59:53 +00002602 Tcl_Interp *interp = Tkapp_Interp(self);
Neal Norwitz44dbae82004-02-19 02:44:22 +00002603 Tk_Window main_window;
David Aschere2b4b322004-02-18 05:59:53 +00002604 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002605 int err;
Neal Norwitz44dbae82004-02-19 02:44:22 +00002606 main_window = Tk_MainWindow(interp);
David Aschere2b4b322004-02-18 05:59:53 +00002607
Thomas Wouters477c8d52006-05-27 19:21:47 +00002608 /* In all current versions of Tk (including 8.4.13), Tk_Init
2609 deadlocks on the second call when the first call failed.
2610 To avoid the deadlock, we just refuse the second call through
2611 a static variable. */
2612 if (has_failed) {
2613 PyErr_SetString(Tkinter_TclError,
2614 "Calling Tk_Init again after a previous call failed might deadlock");
2615 return NULL;
2616 }
2617
David Aschere2b4b322004-02-18 05:59:53 +00002618 /* We want to guard against calling Tk_Init() multiple times */
2619 CHECK_TCL_APPARTMENT;
2620 ENTER_TCL
2621 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2622 ENTER_OVERLAP
2623 if (err == TCL_ERROR) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002624 /* This sets an exception, but we cannot return right
2625 away because we need to exit the overlap first. */
2626 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002627 } else {
2628 _tk_exists = Tkapp_Result(self);
2629 }
2630 LEAVE_OVERLAP_TCL
2631 if (err == TCL_ERROR) {
2632 return NULL;
2633 }
2634 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2635 if (Tk_Init(interp) == TCL_ERROR) {
2636 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
Thomas Wouters477c8d52006-05-27 19:21:47 +00002637 has_failed = 1;
David Aschere2b4b322004-02-18 05:59:53 +00002638 return NULL;
2639 }
2640 }
2641 Py_INCREF(Py_None);
2642 return Py_None;
2643}
Barry Warsawfa701a81997-01-16 00:15:11 +00002644
Martin v. Löwisffad6332002-11-26 09:28:05 +00002645static PyObject *
2646Tkapp_WantObjects(PyObject *self, PyObject *args)
2647{
2648
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002649 int wantobjects = -1;
2650 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002651 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002652 if (wantobjects == -1)
2653 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002654 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002655
2656 Py_INCREF(Py_None);
2657 return Py_None;
2658}
2659
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002660static PyObject *
2661Tkapp_WillDispatch(PyObject *self, PyObject *args)
2662{
2663
2664 ((TkappObject*)self)->dispatching = 1;
2665
2666 Py_INCREF(Py_None);
2667 return Py_None;
2668}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002669
Barry Warsawfa701a81997-01-16 00:15:11 +00002670
Guido van Rossum18468821994-06-20 07:49:28 +00002671/**** Tkapp Method List ****/
2672
2673static PyMethodDef Tkapp_methods[] =
2674{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002675 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002676 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002677 {"call", Tkapp_Call, METH_VARARGS},
2678 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002679 {"eval", Tkapp_Eval, METH_VARARGS},
2680 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2681 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2682 {"record", Tkapp_Record, METH_VARARGS},
2683 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2684 {"setvar", Tkapp_SetVar, METH_VARARGS},
2685 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2686 {"getvar", Tkapp_GetVar, METH_VARARGS},
2687 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2688 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2689 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2690 {"getint", Tkapp_GetInt, METH_VARARGS},
2691 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2692 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2693 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2694 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2695 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2696 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2697 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2698 {"split", Tkapp_Split, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002699 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002700 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2701 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002702#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002703 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2704 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002705#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002706 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2707 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2708 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2709 {"quit", Tkapp_Quit, METH_VARARGS},
2710 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002711 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002712 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002713};
2714
Barry Warsawfa701a81997-01-16 00:15:11 +00002715
2716
Guido van Rossum18468821994-06-20 07:49:28 +00002717/**** Tkapp Type Methods ****/
2718
2719static void
Fred Drake509d79a2000-07-08 04:04:38 +00002720Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002721{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002722 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002723 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002724 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002725 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002726 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002727 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002728}
2729
2730static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002731Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002732{
Guido van Rossum35d43371997-08-02 00:09:09 +00002733 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002734}
2735
2736static PyTypeObject Tkapp_Type =
2737{
Guido van Rossum35d43371997-08-02 00:09:09 +00002738 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002739 0, /*ob_size */
2740 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002741 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002742 0, /*tp_itemsize */
2743 Tkapp_Dealloc, /*tp_dealloc */
2744 0, /*tp_print */
2745 Tkapp_GetAttr, /*tp_getattr */
2746 0, /*tp_setattr */
2747 0, /*tp_compare */
2748 0, /*tp_repr */
2749 0, /*tp_as_number */
2750 0, /*tp_as_sequence */
2751 0, /*tp_as_mapping */
2752 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002753};
2754
Barry Warsawfa701a81997-01-16 00:15:11 +00002755
2756
Guido van Rossum18468821994-06-20 07:49:28 +00002757/**** Tkinter Module ****/
2758
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002759typedef struct {
2760 PyObject* tuple;
2761 int size; /* current size */
2762 int maxsize; /* allocated size */
2763} FlattenContext;
2764
2765static int
2766_bump(FlattenContext* context, int size)
2767{
Guido van Rossum2834b972000-10-06 16:58:26 +00002768 /* expand tuple to hold (at least) size new items.
2769 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002770
2771 int maxsize = context->maxsize * 2;
2772
2773 if (maxsize < context->size + size)
2774 maxsize = context->size + size;
2775
2776 context->maxsize = maxsize;
2777
Tim Peters4324aa32001-05-28 22:30:08 +00002778 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002779}
2780
2781static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002782_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002783{
2784 /* add tuple or list to argument tuple (recursively) */
2785
2786 int i, size;
2787
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002788 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002789 PyErr_SetString(PyExc_ValueError,
2790 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002791 return 0;
2792 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002793 size = PyList_GET_SIZE(item);
2794 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002795 if (context->size + size > context->maxsize &&
2796 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002797 return 0;
2798 /* copy items to output tuple */
2799 for (i = 0; i < size; i++) {
2800 PyObject *o = PyList_GET_ITEM(item, i);
2801 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002802 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002803 return 0;
2804 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002805 if (context->size + 1 > context->maxsize &&
2806 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002807 return 0;
2808 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002809 PyTuple_SET_ITEM(context->tuple,
2810 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002811 }
2812 }
2813 } else if (PyTuple_Check(item)) {
2814 /* same, for tuples */
2815 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002816 if (context->size + size > context->maxsize &&
2817 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002818 return 0;
2819 for (i = 0; i < size; i++) {
2820 PyObject *o = PyTuple_GET_ITEM(item, i);
2821 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002822 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002823 return 0;
2824 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002825 if (context->size + 1 > context->maxsize &&
2826 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002827 return 0;
2828 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002829 PyTuple_SET_ITEM(context->tuple,
2830 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002831 }
2832 }
2833 } else {
2834 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2835 return 0;
2836 }
2837 return 1;
2838}
2839
2840static PyObject *
2841Tkinter_Flatten(PyObject* self, PyObject* args)
2842{
2843 FlattenContext context;
2844 PyObject* item;
2845
2846 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2847 return NULL;
2848
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002849 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002850 if (context.maxsize <= 0)
2851 return PyTuple_New(0);
2852
2853 context.tuple = PyTuple_New(context.maxsize);
2854 if (!context.tuple)
2855 return NULL;
2856
2857 context.size = 0;
2858
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002859 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002860 return NULL;
2861
Tim Peters4324aa32001-05-28 22:30:08 +00002862 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002863 return NULL;
2864
2865 return context.tuple;
2866}
2867
Guido van Rossum18468821994-06-20 07:49:28 +00002868static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002869Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002870{
Barry Warsawfa701a81997-01-16 00:15:11 +00002871 char *screenName = NULL;
2872 char *baseName = NULL;
2873 char *className = NULL;
2874 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002875 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002876 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002877 int sync = 0; /* pass -sync to wish */
2878 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002879
Guido van Rossum35d43371997-08-02 00:09:09 +00002880 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002881 if (baseName != NULL)
2882 baseName++;
2883 else
2884 baseName = Py_GetProgramName();
2885 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002886
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002887 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002888 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002889 &interactive, &wantobjects, &wantTk,
2890 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00002891 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002892
Barry Warsawfa701a81997-01-16 00:15:11 +00002893 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002894 interactive, wantobjects, wantTk,
2895 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002896}
2897
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002898static PyObject *
2899Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2900{
2901 int new_val;
2902 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2903 return NULL;
2904 if (new_val < 0) {
2905 PyErr_SetString(PyExc_ValueError,
2906 "busywaitinterval must be >= 0");
2907 return NULL;
2908 }
2909 Tkinter_busywaitinterval = new_val;
2910 Py_INCREF(Py_None);
2911 return Py_None;
2912}
2913
2914static char setbusywaitinterval_doc[] =
2915"setbusywaitinterval(n) -> None\n\
2916\n\
2917Set the busy-wait interval in milliseconds between successive\n\
2918calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2919It should be set to a divisor of the maximum time between\n\
2920frames in an animation.";
2921
2922static PyObject *
2923Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2924{
2925 return PyInt_FromLong(Tkinter_busywaitinterval);
2926}
2927
2928static char getbusywaitinterval_doc[] =
2929"getbusywaitinterval() -> int\n\
2930\n\
2931Return the current busy-wait interval between successive\n\
2932calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2933
Guido van Rossum18468821994-06-20 07:49:28 +00002934static PyMethodDef moduleMethods[] =
2935{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002936 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2937 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002938#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002939 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2940 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002941#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002942 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2943 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2944 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2945 {"quit", Tkapp_Quit, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002946 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2947 setbusywaitinterval_doc},
2948 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2949 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00002950 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002951};
2952
Guido van Rossum7bf15641998-05-22 18:28:17 +00002953#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002954
2955static int stdin_ready = 0;
2956
Guido van Rossumad4db171998-06-13 13:56:28 +00002957#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002958static void
Fred Drake509d79a2000-07-08 04:04:38 +00002959MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002960{
2961 stdin_ready = 1;
2962}
Guido van Rossumad4db171998-06-13 13:56:28 +00002963#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002964
Martin v. Löwisa9656492003-03-30 08:44:58 +00002965#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002966static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002967#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002968
Guido van Rossum18468821994-06-20 07:49:28 +00002969static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002970EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002971{
Guido van Rossumad4db171998-06-13 13:56:28 +00002972#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002973 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002974#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002975#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002976 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002977#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002978 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002979 errorInCmd = 0;
2980#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002981 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002982 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002983#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002984 while (!errorInCmd && !stdin_ready) {
2985 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002986#ifdef MS_WINDOWS
2987 if (_kbhit()) {
2988 stdin_ready = 1;
2989 break;
2990 }
2991#endif
2992#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002993 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002994 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002995 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002996
Guido van Rossum00d93061998-05-28 23:06:38 +00002997 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002998
2999 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003000 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00003001 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003002 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00003003 Py_END_ALLOW_THREADS
3004#else
3005 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003006#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003007
3008 if (result < 0)
3009 break;
3010 }
Guido van Rossumad4db171998-06-13 13:56:28 +00003011#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00003012 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00003013#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003014 if (errorInCmd) {
3015 errorInCmd = 0;
3016 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3017 excInCmd = valInCmd = trbInCmd = NULL;
3018 PyErr_Print();
3019 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003020#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003021 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003022#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003023 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00003024}
Guido van Rossum18468821994-06-20 07:49:28 +00003025
Guido van Rossum00d93061998-05-28 23:06:38 +00003026#endif
3027
Guido van Rossum7bf15641998-05-22 18:28:17 +00003028static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003029EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003030{
Guido van Rossum00d93061998-05-28 23:06:38 +00003031#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003032 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003033#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003034 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003035#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003036 PyOS_InputHook = EventHook;
3037 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003038#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003039}
3040
3041static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003042DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003043{
Guido van Rossum00d93061998-05-28 23:06:38 +00003044#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003045 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3046 PyOS_InputHook = NULL;
3047 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003048#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003049}
3050
Barry Warsawfa701a81997-01-16 00:15:11 +00003051
3052/* all errors will be checked in one fell swoop in init_tkinter() */
3053static void
Fred Drake509d79a2000-07-08 04:04:38 +00003054ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003055{
3056 PyObject *v = PyInt_FromLong(val);
3057 if (v) {
3058 PyDict_SetItemString(d, name, v);
3059 Py_DECREF(v);
3060 }
3061}
3062static void
Fred Drake509d79a2000-07-08 04:04:38 +00003063ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003064{
3065 PyObject *v = PyString_FromString(val);
3066 if (v) {
3067 PyDict_SetItemString(d, name, v);
3068 Py_DECREF(v);
3069 }
3070}
3071
3072
Mark Hammond62b1ab12002-07-23 06:31:15 +00003073PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003074init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003075{
Barry Warsawfa701a81997-01-16 00:15:11 +00003076 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00003077
Barry Warsawfa701a81997-01-16 00:15:11 +00003078 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00003079
3080#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003081 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003082#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003083
Barry Warsawfa701a81997-01-16 00:15:11 +00003084 m = Py_InitModule("_tkinter", moduleMethods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003085 if (m == NULL)
3086 return;
Guido van Rossum18468821994-06-20 07:49:28 +00003087
Barry Warsawfa701a81997-01-16 00:15:11 +00003088 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003089 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003090 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003091
Guido van Rossum35d43371997-08-02 00:09:09 +00003092 ins_long(d, "READABLE", TCL_READABLE);
3093 ins_long(d, "WRITABLE", TCL_WRITABLE);
3094 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3095 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3096 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3097 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3098 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3099 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3100 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003101 ins_string(d, "TK_VERSION", TK_VERSION);
3102 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003103
Guido van Rossum83551bf1997-09-13 00:44:23 +00003104 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003105
3106 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003107 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3108
Martin v. Löwisffad6332002-11-26 09:28:05 +00003109 PyTclObject_Type.ob_type = &PyType_Type;
3110 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003111
3112#ifdef TK_AQUA
3113 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3114 * start waking up. Note that Tcl_FindExecutable will do this, this
3115 * code must be above it! The original warning from
3116 * tkMacOSXAppInit.c is copied below.
3117 *
3118 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3119 * Tcl interpreter for now. It probably should work to do this
3120 * in the other order, but for now it doesn't seem to.
3121 *
3122 */
3123 Tk_MacOSXSetupTkNotifier();
3124#endif
3125
3126
Guido van Rossume187b0e2000-03-27 21:46:29 +00003127 /* This helps the dynamic loader; in Unicode aware Tcl versions
3128 it also helps Tcl find its encodings. */
3129 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00003130
Barry Warsawfa701a81997-01-16 00:15:11 +00003131 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003132 return;
3133
Guido van Rossum43ff8681998-07-14 18:02:13 +00003134#if 0
3135 /* This was not a good idea; through <Destroy> bindings,
3136 Tcl_Finalize() may invoke Python code but at that point the
3137 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003138 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003139#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003140
Guido van Rossum18468821994-06-20 07:49:28 +00003141}