blob: 507c9da8f8d04b50f07a0afaea4995c448f33e21 [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
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000265#define Tkapp_Check(v) (Py_Type(v) == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000266#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000267#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000268
Guido van Rossum35d43371997-08-02 00:09:09 +0000269#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000270(void *) v, Py_Refcnt(v)))
Guido van Rossum18468821994-06-20 07:49:28 +0000271
Barry Warsawfa701a81997-01-16 00:15:11 +0000272
273
Guido van Rossum18468821994-06-20 07:49:28 +0000274/**** Error Handling ****/
275
276static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000277static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000278static int errorInCmd = 0;
279static PyObject *excInCmd;
280static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000282
Barry Warsawfa701a81997-01-16 00:15:11 +0000283
284
Guido van Rossum18468821994-06-20 07:49:28 +0000285static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000286Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000287{
Barry Warsawfa701a81997-01-16 00:15:11 +0000288 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
289 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000290}
291
Barry Warsawfa701a81997-01-16 00:15:11 +0000292
Barry Warsawfa701a81997-01-16 00:15:11 +0000293
Guido van Rossum18468821994-06-20 07:49:28 +0000294/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000295
Martin v. Löwis28e9ce92003-05-09 08:19:48 +0000296static int Tkinter_busywaitinterval = 20;
297
Guido van Rossum00d93061998-05-28 23:06:38 +0000298#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000299#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000300
Guido van Rossum00d93061998-05-28 23:06:38 +0000301/* Millisecond sleep() for Unix platforms. */
302
303static void
Fred Drake509d79a2000-07-08 04:04:38 +0000304Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000305{
306 /* XXX Too bad if you don't have select(). */
307 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000308 t.tv_sec = milli/1000;
309 t.tv_usec = (milli%1000) * 1000;
310 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
311}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000312#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000313
Martin v. Löwis5b26abb2002-12-28 09:23:09 +0000314/* Wait up to 1s for the mainloop to come up. */
315
316static int
317WaitForMainloop(TkappObject* self)
318{
319 int i;
320 for (i = 0; i < 10; i++) {
321 if (self->dispatching)
322 return 1;
323 Py_BEGIN_ALLOW_THREADS
324 Sleep(100);
325 Py_END_ALLOW_THREADS
326 }
327 if (self->dispatching)
328 return 1;
329 PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
330 return 0;
331}
Martin v. Löwisa9656492003-03-30 08:44:58 +0000332#endif /* WITH_THREAD */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000333
Guido van Rossum00d93061998-05-28 23:06:38 +0000334
Guido van Rossum18468821994-06-20 07:49:28 +0000335static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000336AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000337{
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 */
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000463 return PyUnicode_FromString(list);
Barry Warsawfa701a81997-01-16 00:15:11 +0000464 }
Guido van Rossum18468821994-06-20 07:49:28 +0000465
Barry Warsawfa701a81997-01-16 00:15:11 +0000466 if (argc == 0)
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000467 v = PyUnicode_FromString("");
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 else if (argc == 1)
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000469 v = PyUnicode_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000470 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 int i;
472 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000473
Barry Warsawfa701a81997-01-16 00:15:11 +0000474 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000475 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 Py_DECREF(v);
477 v = NULL;
478 break;
479 }
480 PyTuple_SetItem(v, i, w);
481 }
482 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000483 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000484 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000485}
486
Martin v. Löwisffad6332002-11-26 09:28:05 +0000487/* In some cases, Tcl will still return strings that are supposed to be
488 lists. SplitObj walks through a nested tuple, finding string objects that
489 need to be split. */
490
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
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000745static char*
746PyTclObject_TclString(PyObject *self)
747{
748 return Tcl_GetString(((PyTclObject*)self)->value);
749}
750
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000751/* Like _str, but create Unicode if necessary. */
Martin v. Löwis39195712003-01-04 00:33:13 +0000752PyDoc_STRVAR(PyTclObject_string__doc__,
Walter Dörwalda1884662007-07-12 12:16:02 +0000753"the string representation of this object, either as str8 or str");
Martin v. Löwis39195712003-01-04 00:33:13 +0000754
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000755static PyObject *
756PyTclObject_string(PyTclObject *self, void *ignored)
757{
758 char *s;
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000759 int len;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000760 if (!self->string) {
761 s = Tcl_GetStringFromObj(self->value, &len);
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000762 self->string = PyUnicode_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000763 if (!self->string)
764 return NULL;
765 }
766 Py_INCREF(self->string);
767 return self->string;
768}
769
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000770static PyObject *
Walter Dörwald6720d912007-07-12 12:12:25 +0000771PyTclObject_str(PyTclObject *self, void *ignored)
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000772{
773 char *s;
774 int len;
775 if (self->string && PyUnicode_Check(self->string)) {
776 Py_INCREF(self->string);
777 return self->string;
778 }
779 /* XXX Could chache result if it is non-ASCII. */
780 s = Tcl_GetStringFromObj(self->value, &len);
781 return PyUnicode_DecodeUTF8(s, len, "strict");
782}
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000783
Martin v. Löwisffad6332002-11-26 09:28:05 +0000784static PyObject *
785PyTclObject_repr(PyTclObject *self)
786{
Walter Dörwald7569dfe2007-05-19 21:49:49 +0000787 return PyUnicode_FromFormat("<%s object at %p>",
788 self->value->typePtr->name, self->value);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000789}
790
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000791static int
792PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
793{
794 int res;
795 res = strcmp(Tcl_GetString(self->value),
796 Tcl_GetString(other->value));
797 if (res < 0) return -1;
798 if (res > 0) return 1;
799 return 0;
800}
801
Martin v. Löwis39195712003-01-04 00:33:13 +0000802PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
803
Martin v. Löwisffad6332002-11-26 09:28:05 +0000804static PyObject*
805get_typename(PyTclObject* obj, void* ignored)
806{
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000807 return PyUnicode_FromString(obj->value->typePtr->name);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000808}
809
Martin v. Löwis39195712003-01-04 00:33:13 +0000810
Martin v. Löwisffad6332002-11-26 09:28:05 +0000811static PyGetSetDef PyTclObject_getsetlist[] = {
Martin v. Löwis39195712003-01-04 00:33:13 +0000812 {"typename", (getter)get_typename, NULL, get_typename__doc__},
813 {"string", (getter)PyTclObject_string, NULL,
814 PyTclObject_string__doc__},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000815 {0},
816};
817
Neal Norwitz227b5332006-03-22 09:28:35 +0000818static PyTypeObject PyTclObject_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000819 PyVarObject_HEAD_INIT(NULL, 0)
Martin v. Löwisffad6332002-11-26 09:28:05 +0000820 "_tkinter.Tcl_Obj", /*tp_name*/
821 sizeof(PyTclObject), /*tp_basicsize*/
822 0, /*tp_itemsize*/
823 /* methods */
824 (destructor)PyTclObject_dealloc, /*tp_dealloc*/
825 0, /*tp_print*/
826 0, /*tp_getattr*/
827 0, /*tp_setattr*/
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000828 (cmpfunc)PyTclObject_cmp, /*tp_compare*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000829 (reprfunc)PyTclObject_repr, /*tp_repr*/
830 0, /*tp_as_number*/
831 0, /*tp_as_sequence*/
832 0, /*tp_as_mapping*/
833 0, /*tp_hash*/
834 0, /*tp_call*/
835 (reprfunc)PyTclObject_str, /*tp_str*/
Jason Tishlerfb8595d2003-01-06 12:41:26 +0000836 PyObject_GenericGetAttr,/*tp_getattro*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000837 0, /*tp_setattro*/
838 0, /*tp_as_buffer*/
839 Py_TPFLAGS_DEFAULT, /*tp_flags*/
840 0, /*tp_doc*/
841 0, /*tp_traverse*/
842 0, /*tp_clear*/
843 0, /*tp_richcompare*/
844 0, /*tp_weaklistoffset*/
845 0, /*tp_iter*/
846 0, /*tp_iternext*/
Walter Dörwald6720d912007-07-12 12:12:25 +0000847 0, /*tp_methods*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000848 0, /*tp_members*/
849 PyTclObject_getsetlist, /*tp_getset*/
850 0, /*tp_base*/
851 0, /*tp_dict*/
852 0, /*tp_descr_get*/
853 0, /*tp_descr_set*/
854 0, /*tp_dictoffset*/
855 0, /*tp_init*/
856 0, /*tp_alloc*/
857 0, /*tp_new*/
858 0, /*tp_free*/
859 0, /*tp_is_gc*/
860};
861
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000862static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000863AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000864{
865 Tcl_Obj *result;
866
867 if (PyString_Check(value))
868 return Tcl_NewStringObj(PyString_AS_STRING(value),
869 PyString_GET_SIZE(value));
Martin v. Löwis70c3dda2003-01-22 09:17:38 +0000870 else if (PyBool_Check(value))
871 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
Guido van Rossumddefaf32007-01-14 03:31:43 +0000872 else if (PyInt_CheckExact(value))
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000873 return Tcl_NewLongObj(PyInt_AS_LONG(value));
874 else if (PyFloat_Check(value))
875 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
876 else if (PyTuple_Check(value)) {
877 Tcl_Obj **argv = (Tcl_Obj**)
878 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
879 int i;
880 if(!argv)
881 return 0;
882 for(i=0;i<PyTuple_Size(value);i++)
883 argv[i] = AsObj(PyTuple_GetItem(value,i));
884 result = Tcl_NewListObj(PyTuple_Size(value), argv);
885 ckfree(FREECAST argv);
886 return result;
887 }
888 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000889 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000890 Py_ssize_t size = PyUnicode_GET_SIZE(value);
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000891 /* This #ifdef assumes that Tcl uses UCS-2.
892 See TCL_UTF_MAX test above. */
Martin v. Löwis6f29ff32003-04-16 20:34:55 +0000893#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000894 Tcl_UniChar *outbuf;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000895 Py_ssize_t i;
896 assert(size < size * sizeof(Tcl_UniChar));
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000897 outbuf = (Tcl_UniChar*)ckalloc(size * sizeof(Tcl_UniChar));
898 if (!outbuf) {
899 PyErr_NoMemory();
900 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000901 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000902 for (i = 0; i < size; i++) {
903 if (inbuf[i] >= 0x10000) {
904 /* Tcl doesn't do UTF-16, yet. */
905 PyErr_SetString(PyExc_ValueError,
906 "unsupported character");
907 ckfree(FREECAST outbuf);
908 return NULL;
909 }
910 outbuf[i] = inbuf[i];
911 }
912 result = Tcl_NewUnicodeObj(outbuf, size);
913 ckfree(FREECAST outbuf);
914 return result;
915#else
916 return Tcl_NewUnicodeObj(inbuf, size);
917#endif
918
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000919 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000920 else if(PyTclObject_Check(value)) {
921 Tcl_Obj *v = ((PyTclObject*)value)->value;
922 Tcl_IncrRefCount(v);
923 return v;
924 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000925 else {
926 PyObject *v = PyObject_Str(value);
927 if (!v)
928 return 0;
929 result = AsObj(v);
930 Py_DECREF(v);
931 return result;
932 }
933}
934
Martin v. Löwisffad6332002-11-26 09:28:05 +0000935static PyObject*
936FromObj(PyObject* tkapp, Tcl_Obj *value)
937{
938 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000939 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000940
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000941 if (value->typePtr == NULL) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000942 return PyUnicode_FromStringAndSize(value->bytes,
943 value->length);
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000944 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000945
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000946 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000947 result = value->internalRep.longValue ? Py_True : Py_False;
948 Py_INCREF(result);
949 return result;
950 }
951
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000952 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000953 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +0000954 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000955 return PyBytes_FromStringAndSize(data, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000956 }
957
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000958 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000959 return PyFloat_FromDouble(value->internalRep.doubleValue);
960 }
961
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000962 if (value->typePtr == app->IntType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000963 return PyInt_FromLong(value->internalRep.longValue);
964 }
965
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000966 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000967 int size;
968 int i, status;
969 PyObject *elem;
970 Tcl_Obj *tcl_elem;
971
972 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
973 if (status == TCL_ERROR)
974 return Tkinter_Error(tkapp);
975 result = PyTuple_New(size);
976 if (!result)
977 return NULL;
978 for (i = 0; i < size; i++) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000979 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
Martin v. Löwisffad6332002-11-26 09:28:05 +0000980 value, i, &tcl_elem);
981 if (status == TCL_ERROR) {
982 Py_DECREF(result);
983 return Tkinter_Error(tkapp);
984 }
985 elem = FromObj(tkapp, tcl_elem);
986 if (!elem) {
987 Py_DECREF(result);
988 return NULL;
989 }
990 PyTuple_SetItem(result, i, elem);
991 }
992 return result;
993 }
994
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000995 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000996 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000997 }
998
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000999 if (value->typePtr == app->StringType) {
Martin v. Löwis6f29ff32003-04-16 20:34:55 +00001000#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
Martin v. Löwisffad6332002-11-26 09:28:05 +00001001 PyObject *result;
1002 int size;
1003 Tcl_UniChar *input;
1004 Py_UNICODE *output;
1005
1006 size = Tcl_GetCharLength(value);
1007 result = PyUnicode_FromUnicode(NULL, size);
1008 if (!result)
1009 return NULL;
1010 input = Tcl_GetUnicode(value);
1011 output = PyUnicode_AS_UNICODE(result);
1012 while (size--)
1013 *output++ = *input++;
1014 return result;
1015#else
1016 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1017 Tcl_GetCharLength(value));
1018#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +00001019 }
1020
1021 return newPyTclObject(value);
1022}
1023
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001024/* This mutex synchronizes inter-thread command calls. */
1025
1026TCL_DECLARE_MUTEX(call_mutex)
1027
1028typedef struct Tkapp_CallEvent {
1029 Tcl_Event ev; /* Must be first */
1030 TkappObject *self;
1031 PyObject *args;
1032 int flags;
1033 PyObject **res;
1034 PyObject **exc_type, **exc_value, **exc_tb;
1035 Tcl_Condition done;
1036} Tkapp_CallEvent;
1037
1038void
1039Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001040{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001041 int i;
1042 for (i = 0; i < objc; i++)
1043 Tcl_DecrRefCount(objv[i]);
1044 if (objv != objStore)
1045 ckfree(FREECAST objv);
1046}
Guido van Rossum18468821994-06-20 07:49:28 +00001047
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001048/* Convert Python objects to Tcl objects. This must happen in the
1049 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001050
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001051static Tcl_Obj**
1052Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1053{
1054 Tcl_Obj **objv = objStore;
Martin v. Löwis7d134952002-12-12 19:05:48 +00001055 int objc = 0, i;
Guido van Rossum212643f1998-04-29 16:22:14 +00001056 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +00001057 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001058
Guido van Rossum212643f1998-04-29 16:22:14 +00001059 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +00001060 objv[0] = AsObj(args);
1061 if (objv[0] == 0)
1062 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001063 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +00001064 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001065 }
1066 else {
Guido van Rossum632de272000-03-29 00:19:50 +00001067 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001068
Guido van Rossum632de272000-03-29 00:19:50 +00001069 if (objc > ARGSZ) {
1070 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1071 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001072 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +00001073 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +00001074 goto finally;
1075 }
1076 }
1077
Guido van Rossum632de272000-03-29 00:19:50 +00001078 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001079 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +00001080 if (v == Py_None) {
1081 objc = i;
1082 break;
1083 }
Guido van Rossum632de272000-03-29 00:19:50 +00001084 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +00001085 if (!objv[i]) {
1086 /* Reset objc, so it attempts to clear
1087 objects only up to i. */
1088 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +00001089 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001090 }
Guido van Rossum632de272000-03-29 00:19:50 +00001091 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001092 }
1093 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001094 *pobjc = objc;
1095 return objv;
1096finally:
1097 Tkapp_CallDeallocArgs(objv, objStore, objc);
1098 return NULL;
1099}
Guido van Rossum212643f1998-04-29 16:22:14 +00001100
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001101/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001102
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001103static PyObject*
1104Tkapp_CallResult(TkappObject *self)
1105{
1106 PyObject *res = NULL;
1107 if(self->wantobjects) {
1108 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001109 /* Not sure whether the IncrRef is necessary, but something
1110 may overwrite the interpreter result while we are
1111 converting it. */
1112 Tcl_IncrRefCount(value);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001113 res = FromObj((PyObject*)self, value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001114 Tcl_DecrRefCount(value);
1115 } else {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001116 const char *s = Tcl_GetStringResult(self->interp);
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001117 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001118
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001119 res = PyUnicode_FromStringAndSize(s, (int)(p-s));
Guido van Rossum990f5c62000-05-04 15:07:16 +00001120 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001121 return res;
1122}
Guido van Rossum632de272000-03-29 00:19:50 +00001123
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001124/* Tkapp_CallProc is the event procedure that is executed in the context of
1125 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1126 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001127
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001128static int
1129Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1130{
1131 Tcl_Obj *objStore[ARGSZ];
1132 Tcl_Obj **objv;
1133 int objc;
1134 int i;
1135 ENTER_PYTHON
1136 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1137 if (!objv) {
1138 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1139 *(e->res) = NULL;
1140 }
1141 LEAVE_PYTHON
1142 if (!objv)
1143 goto done;
1144 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1145 ENTER_PYTHON
1146 if (i == TCL_ERROR) {
1147 *(e->res) = NULL;
1148 *(e->exc_type) = NULL;
1149 *(e->exc_tb) = NULL;
1150 *(e->exc_value) = PyObject_CallFunction(
1151 Tkinter_TclError, "s",
1152 Tcl_GetStringResult(e->self->interp));
1153 }
1154 else {
1155 *(e->res) = Tkapp_CallResult(e->self);
1156 }
1157 LEAVE_PYTHON
1158 done:
1159 /* Wake up calling thread. */
1160 Tcl_MutexLock(&call_mutex);
1161 Tcl_ConditionNotify(&e->done);
1162 Tcl_MutexUnlock(&call_mutex);
1163 return 1;
1164}
1165
1166/* This is the main entry point for calling a Tcl command.
1167 It supports three cases, with regard to threading:
1168 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1169 the context of the calling thread.
1170 2. Tcl is threaded, caller of the command is in the interpreter thread:
1171 Execute the command in the calling thread. Since the Tcl lock will
1172 not be used, we can merge that with case 1.
1173 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1174 the interpreter thread. Allocation of Tcl objects needs to occur in the
1175 interpreter thread, so we ship the PyObject* args to the target thread,
1176 and perform processing there. */
1177
1178static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001179Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001180{
1181 Tcl_Obj *objStore[ARGSZ];
1182 Tcl_Obj **objv = NULL;
1183 int objc, i;
1184 PyObject *res = NULL;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001185 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001186 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
1187 int flags = TCL_EVAL_DIRECT;
1188
Guido van Rossum992d4a32007-07-11 13:09:30 +00001189 /* If args is a single tuple, replace with contents of tuple */
1190 if (1 == PyTuple_Size(args)){
1191 PyObject* item = PyTuple_GetItem(args, 0);
1192 if (PyTuple_Check(item))
1193 args = item;
1194 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001195#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001196 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1197 /* We cannot call the command directly. Instead, we must
1198 marshal the parameters to the interpreter thread. */
1199 Tkapp_CallEvent *ev;
1200 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001201 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001202 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001203 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1204 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1205 ev->self = self;
1206 ev->args = args;
1207 ev->res = &res;
1208 ev->exc_type = &exc_type;
1209 ev->exc_value = &exc_value;
1210 ev->exc_tb = &exc_tb;
1211 ev->done = (Tcl_Condition)0;
1212
1213 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &call_mutex);
1214
1215 if (res == NULL) {
1216 if (exc_type)
1217 PyErr_Restore(exc_type, exc_value, exc_tb);
1218 else
1219 PyErr_SetObject(Tkinter_TclError, exc_value);
1220 }
1221 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001222 else
1223#endif
1224 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001225
1226 objv = Tkapp_CallArgs(args, objStore, &objc);
1227 if (!objv)
1228 return NULL;
1229
1230 ENTER_TCL
1231
1232 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1233
1234 ENTER_OVERLAP
1235
1236 if (i == TCL_ERROR)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001237 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001238 else
1239 res = Tkapp_CallResult(self);
1240
1241 LEAVE_OVERLAP_TCL
1242
1243 Tkapp_CallDeallocArgs(objv, objStore, objc);
1244 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001245 return res;
1246}
1247
1248
1249static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001250Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001251{
Guido van Rossum212643f1998-04-29 16:22:14 +00001252 /* Could do the same here as for Tkapp_Call(), but this is not used
1253 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1254 way for the user to do what all its Global* variants do (save and
1255 reset the scope pointer, call the local version, restore the saved
1256 scope pointer). */
1257
Guido van Rossum62320c91998-06-15 04:36:09 +00001258 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001259 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001260
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001261 CHECK_TCL_APPARTMENT;
1262
Guido van Rossum62320c91998-06-15 04:36:09 +00001263 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001264 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001265 int err;
1266 ENTER_TCL
1267 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001268 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001269 if (err == TCL_ERROR)
1270 res = Tkinter_Error(self);
1271 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001272 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001273 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001274 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001275 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001276
1277 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001278}
1279
1280static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001281Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001282{
Barry Warsawfa701a81997-01-16 00:15:11 +00001283 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001284 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001285 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001286
Guido van Rossum43713e52000-02-29 13:59:29 +00001287 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001288 return NULL;
1289
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001290 CHECK_TCL_APPARTMENT;
1291
Guido van Rossum00d93061998-05-28 23:06:38 +00001292 ENTER_TCL
1293 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001294 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001295 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001296 res = Tkinter_Error(self);
1297 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001298 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001299 LEAVE_OVERLAP_TCL
1300 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001301}
1302
1303static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001304Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001305{
Barry Warsawfa701a81997-01-16 00:15:11 +00001306 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001307 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001308 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001309
Guido van Rossum43713e52000-02-29 13:59:29 +00001310 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001311 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001312
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001313 CHECK_TCL_APPARTMENT;
1314
Guido van Rossum00d93061998-05-28 23:06:38 +00001315 ENTER_TCL
1316 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001317 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001318 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001319 res = Tkinter_Error(self);
1320 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001321 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001322 LEAVE_OVERLAP_TCL
1323 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001324}
1325
1326static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001327Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001328{
Barry Warsawfa701a81997-01-16 00:15:11 +00001329 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001330 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001331 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001332
Guido van Rossum43713e52000-02-29 13:59:29 +00001333 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001334 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001335
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001336 CHECK_TCL_APPARTMENT;
1337
Guido van Rossum00d93061998-05-28 23:06:38 +00001338 ENTER_TCL
1339 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001340 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001341 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001342 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001343
Guido van Rossum62320c91998-06-15 04:36:09 +00001344 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001345 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001346 LEAVE_OVERLAP_TCL
1347 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001348}
1349
1350static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001351Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001352{
Barry Warsawfa701a81997-01-16 00:15:11 +00001353 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001354 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001355 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001356
Guido van Rossum35d43371997-08-02 00:09:09 +00001357 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001358 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001359
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001360 CHECK_TCL_APPARTMENT;
1361
Guido van Rossum00d93061998-05-28 23:06:38 +00001362 ENTER_TCL
1363 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001364 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001365 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001366 res = Tkinter_Error(self);
1367 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001368 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001369 LEAVE_OVERLAP_TCL
1370 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001371}
1372
1373static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001374Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001375{
Barry Warsawfa701a81997-01-16 00:15:11 +00001376 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001377
Guido van Rossum43713e52000-02-29 13:59:29 +00001378 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001379 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001380 CHECK_TCL_APPARTMENT;
1381
Guido van Rossum00d93061998-05-28 23:06:38 +00001382 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001383 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001384 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001385
Barry Warsawfa701a81997-01-16 00:15:11 +00001386 Py_INCREF(Py_None);
1387 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001388}
1389
Barry Warsawfa701a81997-01-16 00:15:11 +00001390
1391
Guido van Rossum18468821994-06-20 07:49:28 +00001392/** Tcl Variable **/
1393
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001394TCL_DECLARE_MUTEX(var_mutex)
1395
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001396typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001397typedef struct VarEvent {
1398 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001399 PyObject *self;
1400 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001401 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001402 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001403 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001404 PyObject **exc_type;
1405 PyObject **exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001406 Tcl_Condition cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001407} VarEvent;
1408
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001409static int
1410varname_converter(PyObject *in, void *_out)
1411{
1412 char **out = (char**)_out;
1413 if (PyString_Check(in)) {
1414 *out = PyString_AsString(in);
1415 return 1;
1416 }
Guido van Rossumf761e102007-07-23 18:34:37 +00001417 if (PyUnicode_Check(in)) {
1418 *out = PyUnicode_AsString(in);
1419 return 1;
1420 }
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001421 if (PyTclObject_Check(in)) {
1422 *out = PyTclObject_TclString(in);
1423 return 1;
1424 }
1425 /* XXX: Should give diagnostics. */
1426 return 0;
1427}
1428
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001429void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001430var_perform(VarEvent *ev)
1431{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001432 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1433 if (!*(ev->res)) {
1434 PyObject *exc, *val, *tb;
1435 PyErr_Fetch(&exc, &val, &tb);
1436 PyErr_NormalizeException(&exc, &val, &tb);
1437 *(ev->exc_type) = exc;
1438 *(ev->exc_val) = val;
1439 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001440 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001441
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001442}
1443
1444static int
1445var_proc(VarEvent* ev, int flags)
1446{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001447 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001448 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001449 Tcl_MutexLock(&var_mutex);
1450 Tcl_ConditionNotify(&ev->cond);
1451 Tcl_MutexUnlock(&var_mutex);
1452 LEAVE_PYTHON
1453 return 1;
1454}
1455
1456static PyObject*
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001457var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001458{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001459 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisa9656492003-03-30 08:44:58 +00001460#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001461 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001462 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001463 VarEvent *ev;
1464 PyObject *res, *exc_type, *exc_val;
1465
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001466 /* The current thread is not the interpreter thread. Marshal
1467 the call to the interpreter thread, then wait for
1468 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001469 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001470 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001471
1472 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1473
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001474 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001475 ev->args = args;
1476 ev->flags = flags;
1477 ev->func = func;
1478 ev->res = &res;
1479 ev->exc_type = &exc_type;
1480 ev->exc_val = &exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001481 ev->cond = NULL;
1482 ev->ev.proc = (Tcl_EventProc*)var_proc;
1483 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001484 if (!res) {
1485 PyErr_SetObject(exc_type, exc_val);
1486 Py_DECREF(exc_type);
1487 Py_DECREF(exc_val);
1488 return NULL;
1489 }
1490 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001491 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001492#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001493 /* Tcl is not threaded, or this is the interpreter thread. */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001494 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001495}
1496
Guido van Rossum18468821994-06-20 07:49:28 +00001497static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001498SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001499{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001500 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001501 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001502 PyObject *res = NULL;
1503 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001504
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001505 if (PyArg_ParseTuple(args, "O&O:setvar",
1506 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001507 /* XXX Acquire tcl lock??? */
1508 newval = AsObj(newValue);
1509 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001510 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001511 ENTER_TCL
1512 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1513 newval, flags);
1514 ENTER_OVERLAP
1515 if (!ok)
1516 Tkinter_Error(self);
1517 else {
1518 res = Py_None;
1519 Py_INCREF(res);
1520 }
1521 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001522 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001523 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001524 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001525 if (PyArg_ParseTuple(args, "ssO:setvar",
1526 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001527 /* XXX must hold tcl lock already??? */
1528 newval = AsObj(newValue);
1529 ENTER_TCL
1530 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1531 ENTER_OVERLAP
1532 if (!ok)
1533 Tkinter_Error(self);
1534 else {
1535 res = Py_None;
1536 Py_INCREF(res);
1537 }
1538 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001539 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001540 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001541 return NULL;
1542 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001543 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001544 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001545}
1546
1547static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001548Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001549{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001550 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001551}
1552
1553static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001554Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001555{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001556 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001557}
1558
Barry Warsawfa701a81997-01-16 00:15:11 +00001559
1560
Guido van Rossum18468821994-06-20 07:49:28 +00001561static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001562GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001563{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001564 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001565 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001566 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001567
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001568 if (!PyArg_ParseTuple(args, "O&|s:getvar",
1569 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001570 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001571
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001572 ENTER_TCL
1573 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1574 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001575 if (tres == NULL) {
1576 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1577 } else {
1578 if (((TkappObject*)self)->wantobjects) {
1579 res = FromObj(self, tres);
1580 }
1581 else {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001582 res = PyUnicode_FromString(Tcl_GetString(tres));
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001583 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001584 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001585 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001586 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001587}
1588
1589static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001590Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001591{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001592 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001593}
1594
1595static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001596Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001597{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001598 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001599}
1600
Barry Warsawfa701a81997-01-16 00:15:11 +00001601
1602
Guido van Rossum18468821994-06-20 07:49:28 +00001603static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001604UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001605{
Guido van Rossum35d43371997-08-02 00:09:09 +00001606 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001607 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001608 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001609
Guido van Rossum43713e52000-02-29 13:59:29 +00001610 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001611 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001612
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001613 ENTER_TCL
1614 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1615 ENTER_OVERLAP
1616 if (code == TCL_ERROR)
1617 res = Tkinter_Error(self);
1618 else {
1619 Py_INCREF(Py_None);
1620 res = Py_None;
1621 }
1622 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001623 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001624}
1625
1626static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001627Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001628{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001629 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001630}
1631
1632static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001633Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001634{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001635 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001636}
1637
Barry Warsawfa701a81997-01-16 00:15:11 +00001638
1639
Guido van Rossum18468821994-06-20 07:49:28 +00001640/** Tcl to Python **/
1641
1642static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001643Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001644{
Barry Warsawfa701a81997-01-16 00:15:11 +00001645 char *s;
1646 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001647
Martin v. Löwisffad6332002-11-26 09:28:05 +00001648 if (PyTuple_Size(args) == 1) {
1649 PyObject* o = PyTuple_GetItem(args, 0);
1650 if (PyInt_Check(o)) {
1651 Py_INCREF(o);
1652 return o;
1653 }
1654 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001655 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001656 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001657 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001658 return Tkinter_Error(self);
1659 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001660}
1661
1662static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001663Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001664{
Barry Warsawfa701a81997-01-16 00:15:11 +00001665 char *s;
1666 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001667
Martin v. Löwisffad6332002-11-26 09:28:05 +00001668 if (PyTuple_Size(args) == 1) {
1669 PyObject *o = PyTuple_GetItem(args, 0);
1670 if (PyFloat_Check(o)) {
1671 Py_INCREF(o);
1672 return o;
1673 }
1674 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001675 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001676 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001677 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001678 return Tkinter_Error(self);
1679 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001680}
1681
1682static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001683Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001684{
Barry Warsawfa701a81997-01-16 00:15:11 +00001685 char *s;
1686 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001687
Martin v. Löwisffad6332002-11-26 09:28:05 +00001688 if (PyTuple_Size(args) == 1) {
1689 PyObject *o = PyTuple_GetItem(args, 0);
1690 if (PyInt_Check(o)) {
1691 Py_INCREF(o);
1692 return o;
1693 }
1694 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001695 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001696 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001697 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1698 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001699 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001700}
1701
1702static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001703Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001704{
Barry Warsawfa701a81997-01-16 00:15:11 +00001705 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001706 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001707 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001708
Guido van Rossum43713e52000-02-29 13:59:29 +00001709 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001710 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001711
1712 CHECK_TCL_APPARTMENT;
1713
Guido van Rossum00d93061998-05-28 23:06:38 +00001714 ENTER_TCL
1715 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001716 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001717 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001718 res = Tkinter_Error(self);
1719 else
1720 res = Py_BuildValue("s", Tkapp_Result(self));
1721 LEAVE_OVERLAP_TCL
1722 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001723}
1724
1725static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001726Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001727{
Barry Warsawfa701a81997-01-16 00:15:11 +00001728 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001729 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001730 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001731 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001732
Guido van Rossum43713e52000-02-29 13:59:29 +00001733 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001734 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001735
1736 CHECK_TCL_APPARTMENT;
1737
Guido van Rossum00d93061998-05-28 23:06:38 +00001738 ENTER_TCL
1739 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001740 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001741 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001742 res = Tkinter_Error(self);
1743 else
1744 res = Py_BuildValue("l", v);
1745 LEAVE_OVERLAP_TCL
1746 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001747}
1748
1749static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001750Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001751{
Barry Warsawfa701a81997-01-16 00:15:11 +00001752 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001753 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001754 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001755 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001756
Guido van Rossum43713e52000-02-29 13:59:29 +00001757 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001758 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001759 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001760 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001761 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001762 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001763 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001764 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001765 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001766 res = Tkinter_Error(self);
1767 else
1768 res = Py_BuildValue("d", v);
1769 LEAVE_OVERLAP_TCL
1770 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001771}
1772
1773static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001774Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001775{
Barry Warsawfa701a81997-01-16 00:15:11 +00001776 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001777 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001778 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001779 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001780
Guido van Rossum43713e52000-02-29 13:59:29 +00001781 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001782 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001783 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001784 ENTER_TCL
1785 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001786 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001787 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001788 res = Tkinter_Error(self);
1789 else
1790 res = Py_BuildValue("i", v);
1791 LEAVE_OVERLAP_TCL
1792 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001793}
1794
Barry Warsawfa701a81997-01-16 00:15:11 +00001795
1796
Guido van Rossum18468821994-06-20 07:49:28 +00001797static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001798Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001799{
Barry Warsawfa701a81997-01-16 00:15:11 +00001800 char *list;
1801 int argc;
1802 char **argv;
1803 PyObject *v;
1804 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001805
Martin v. Löwisffad6332002-11-26 09:28:05 +00001806 if (PyTuple_Size(args) == 1) {
1807 v = PyTuple_GetItem(args, 0);
1808 if (PyTuple_Check(v)) {
1809 Py_INCREF(v);
1810 return v;
1811 }
1812 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001813 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001814 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001815
Neal Norwitzd1c55102003-05-29 00:17:03 +00001816 if (Tcl_SplitList(Tkapp_Interp(self), list,
1817 &argc, &argv) == TCL_ERROR) {
1818 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001819 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001820 }
Guido van Rossum18468821994-06-20 07:49:28 +00001821
Barry Warsawfa701a81997-01-16 00:15:11 +00001822 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001823 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001824
Barry Warsawfa701a81997-01-16 00:15:11 +00001825 for (i = 0; i < argc; i++) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001826 PyObject *s = PyUnicode_FromString(argv[i]);
Barry Warsawfa701a81997-01-16 00:15:11 +00001827 if (!s || PyTuple_SetItem(v, i, s)) {
1828 Py_DECREF(v);
1829 v = NULL;
1830 goto finally;
1831 }
1832 }
Guido van Rossum18468821994-06-20 07:49:28 +00001833
Barry Warsawfa701a81997-01-16 00:15:11 +00001834 finally:
1835 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001836 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001837 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001838}
1839
1840static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001841Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001842{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001843 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001844 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001845
Martin v. Löwisffad6332002-11-26 09:28:05 +00001846 if (PyTuple_Size(args) == 1) {
1847 PyObject* o = PyTuple_GetItem(args, 0);
1848 if (PyTuple_Check(o)) {
1849 o = SplitObj(o);
1850 return o;
1851 }
1852 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001853 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001854 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00001855 v = Split(list);
1856 PyMem_Free(list);
1857 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001858}
1859
1860static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001861Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001862{
Barry Warsawfa701a81997-01-16 00:15:11 +00001863 char *s = Merge(args);
1864 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001865
Barry Warsawfa701a81997-01-16 00:15:11 +00001866 if (s) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001867 res = PyUnicode_FromString(s);
Barry Warsawfa701a81997-01-16 00:15:11 +00001868 ckfree(s);
1869 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001870
1871 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001872}
1873
Barry Warsawfa701a81997-01-16 00:15:11 +00001874
1875
Guido van Rossum18468821994-06-20 07:49:28 +00001876/** Tcl Command **/
1877
Guido van Rossum00d93061998-05-28 23:06:38 +00001878/* Client data struct */
1879typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001880 PyObject *self;
1881 PyObject *func;
1882} PythonCmd_ClientData;
1883
1884static int
Fred Drake509d79a2000-07-08 04:04:38 +00001885PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001886{
1887 errorInCmd = 1;
1888 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1889 LEAVE_PYTHON
1890 return TCL_ERROR;
1891}
1892
Guido van Rossum18468821994-06-20 07:49:28 +00001893/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001894 * function or method.
1895 */
Guido van Rossum18468821994-06-20 07:49:28 +00001896static int
Fred Drake509d79a2000-07-08 04:04:38 +00001897PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001898{
Guido van Rossum00d93061998-05-28 23:06:38 +00001899 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Kurt B. Kaiserab45e272007-08-27 01:55:21 +00001900 PyObject *self, *func, *arg, *res, *s;
Guido van Rossum2834b972000-10-06 16:58:26 +00001901 int i, rv;
Martin v. Löwis50fb8662007-08-13 05:41:41 +00001902 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001903
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001904 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001905
Barry Warsawfa701a81997-01-16 00:15:11 +00001906 /* TBD: no error checking here since we know, via the
1907 * Tkapp_CreateCommand() that the client data is a two-tuple
1908 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001909 self = data->self;
1910 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001911
Barry Warsawfa701a81997-01-16 00:15:11 +00001912 /* Create argument list (argv1, ..., argvN) */
1913 if (!(arg = PyTuple_New(argc - 1)))
1914 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001915
Barry Warsawfa701a81997-01-16 00:15:11 +00001916 for (i = 0; i < (argc - 1); i++) {
Kurt B. Kaiserab45e272007-08-27 01:55:21 +00001917 if (11 == (i + 1)) { /* the %A arg is the unicode char */
1918 char *a = argv[i + 1];
1919 s = PyUnicode_FromUnicode((Py_UNICODE *) a, strlen(a));
1920 }
1921 else {
1922 s = PyUnicode_FromString(argv[i + 1]);
1923 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001924 if (!s || PyTuple_SetItem(arg, i, s)) {
1925 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001926 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001927 }
1928 }
1929 res = PyEval_CallObject(func, arg);
1930 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001931
Barry Warsawfa701a81997-01-16 00:15:11 +00001932 if (res == NULL)
1933 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001934
Martin v. Löwis50fb8662007-08-13 05:41:41 +00001935 tres = AsObj(res);
1936 if (tres == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001937 Py_DECREF(res);
1938 return PythonCmd_Error(interp);
1939 }
Guido van Rossum2834b972000-10-06 16:58:26 +00001940 else {
Martin v. Löwis50fb8662007-08-13 05:41:41 +00001941 Tcl_SetObjResult(Tkapp_Interp(self), tres);
Guido van Rossum2834b972000-10-06 16:58:26 +00001942 rv = TCL_OK;
1943 }
1944
Barry Warsawfa701a81997-01-16 00:15:11 +00001945 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00001946
Guido van Rossum00d93061998-05-28 23:06:38 +00001947 LEAVE_PYTHON
1948
Guido van Rossum2834b972000-10-06 16:58:26 +00001949 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001950}
1951
1952static void
Fred Drake509d79a2000-07-08 04:04:38 +00001953PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001954{
Guido van Rossum00d93061998-05-28 23:06:38 +00001955 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1956
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001957 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001958 Py_XDECREF(data->self);
1959 Py_XDECREF(data->func);
1960 PyMem_DEL(data);
1961 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001962}
1963
Barry Warsawfa701a81997-01-16 00:15:11 +00001964
1965
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001966
1967TCL_DECLARE_MUTEX(command_mutex)
1968
1969typedef struct CommandEvent{
1970 Tcl_Event ev;
1971 Tcl_Interp* interp;
1972 char *name;
1973 int create;
1974 int *status;
1975 ClientData *data;
1976 Tcl_Condition done;
1977} CommandEvent;
1978
1979static int
1980Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001981{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001982 if (ev->create)
1983 *ev->status = Tcl_CreateCommand(
1984 ev->interp, ev->name, PythonCmd,
1985 ev->data, PythonCmdDelete) == NULL;
1986 else
1987 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
1988 Tcl_MutexLock(&command_mutex);
1989 Tcl_ConditionNotify(&ev->done);
1990 Tcl_MutexUnlock(&command_mutex);
1991 return 1;
1992}
1993
1994static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001995Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001996{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001997 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00001998 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001999 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002000 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002001 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002002
Guido van Rossum43713e52000-02-29 13:59:29 +00002003 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002004 return NULL;
2005 if (!PyCallable_Check(func)) {
2006 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002007 return NULL;
2008 }
Guido van Rossum18468821994-06-20 07:49:28 +00002009
Martin v. Löwisa9656492003-03-30 08:44:58 +00002010#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002011 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002012 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002013 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002014#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002015
Guido van Rossum00d93061998-05-28 23:06:38 +00002016 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002017 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002018 return PyErr_NoMemory();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002019 Py_INCREF(self);
2020 Py_INCREF(func);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002021 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002022 data->func = func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002023
2024 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2025 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2026 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2027 ev->interp = self->interp;
2028 ev->create = 1;
2029 ev->name = cmdName;
2030 ev->data = (ClientData)data;
2031 ev->status = &err;
2032 ev->done = NULL;
2033 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
2034 }
2035 else {
2036 ENTER_TCL
2037 err = Tcl_CreateCommand(
2038 Tkapp_Interp(self), cmdName, PythonCmd,
2039 (ClientData)data, PythonCmdDelete) == NULL;
2040 LEAVE_TCL
2041 }
2042 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002043 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002044 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002045 return NULL;
2046 }
Guido van Rossum18468821994-06-20 07:49:28 +00002047
Barry Warsawfa701a81997-01-16 00:15:11 +00002048 Py_INCREF(Py_None);
2049 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002050}
2051
Barry Warsawfa701a81997-01-16 00:15:11 +00002052
2053
Guido van Rossum18468821994-06-20 07:49:28 +00002054static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002055Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002056{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002057 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002058 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002059 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002060
Guido van Rossum43713e52000-02-29 13:59:29 +00002061 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002062 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002063 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2064 CommandEvent *ev;
2065 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2066 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2067 ev->interp = self->interp;
2068 ev->create = 0;
2069 ev->name = cmdName;
2070 ev->status = &err;
2071 ev->done = NULL;
2072 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done,
2073 &command_mutex);
2074 }
2075 else {
2076 ENTER_TCL
2077 err = Tcl_DeleteCommand(self->interp, cmdName);
2078 LEAVE_TCL
2079 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002080 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002081 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2082 return NULL;
2083 }
2084 Py_INCREF(Py_None);
2085 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002086}
2087
Barry Warsawfa701a81997-01-16 00:15:11 +00002088
2089
Guido van Rossum00d93061998-05-28 23:06:38 +00002090#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002091/** File Handler **/
2092
Guido van Rossum00d93061998-05-28 23:06:38 +00002093typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002094 PyObject *func;
2095 PyObject *file;
2096 int id;
2097 struct _fhcdata *next;
2098} FileHandler_ClientData;
2099
2100static FileHandler_ClientData *HeadFHCD;
2101
2102static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002103NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002104{
2105 FileHandler_ClientData *p;
2106 p = PyMem_NEW(FileHandler_ClientData, 1);
2107 if (p != NULL) {
2108 Py_XINCREF(func);
2109 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002110 p->func = func;
2111 p->file = file;
2112 p->id = id;
2113 p->next = HeadFHCD;
2114 HeadFHCD = p;
2115 }
2116 return p;
2117}
2118
2119static void
Fred Drake509d79a2000-07-08 04:04:38 +00002120DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002121{
2122 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002123
2124 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002125 while ((p = *pp) != NULL) {
2126 if (p->id == id) {
2127 *pp = p->next;
2128 Py_XDECREF(p->func);
2129 Py_XDECREF(p->file);
2130 PyMem_DEL(p);
2131 }
2132 else
2133 pp = &p->next;
2134 }
2135}
2136
Guido van Rossuma597dde1995-01-10 20:56:29 +00002137static void
Fred Drake509d79a2000-07-08 04:04:38 +00002138FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002139{
Guido van Rossum00d93061998-05-28 23:06:38 +00002140 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002141 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002142
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002143 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002144 func = data->func;
2145 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002146
Barry Warsawfa701a81997-01-16 00:15:11 +00002147 arg = Py_BuildValue("(Oi)", file, (long) mask);
2148 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002149 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002150
2151 if (res == NULL) {
2152 errorInCmd = 1;
2153 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2154 }
2155 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002156 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002157}
2158
Guido van Rossum18468821994-06-20 07:49:28 +00002159static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002160Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2161 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002162{
Guido van Rossum00d93061998-05-28 23:06:38 +00002163 FileHandler_ClientData *data;
2164 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002165 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002166
Guido van Rossum2834b972000-10-06 16:58:26 +00002167 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2168 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002169 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002170
Martin v. Löwisa9656492003-03-30 08:44:58 +00002171#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002172 if (!self && !tcl_lock) {
2173 /* We don't have the Tcl lock since Tcl is threaded. */
2174 PyErr_SetString(PyExc_RuntimeError,
2175 "_tkinter.createfilehandler not supported "
2176 "for threaded Tcl");
2177 return NULL;
2178 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002179#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002180
2181 if (self) {
2182 CHECK_TCL_APPARTMENT;
2183 }
2184
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002185 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002186 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002187 return NULL;
2188 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002189 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002190 return NULL;
2191 }
2192
Guido van Rossuma80649b2000-03-28 20:07:05 +00002193 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002194 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002195 return NULL;
2196
Barry Warsawfa701a81997-01-16 00:15:11 +00002197 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002198 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002199 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002200 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002201 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002202 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002203}
2204
2205static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002206Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002207{
Barry Warsawfa701a81997-01-16 00:15:11 +00002208 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002209 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002210
Guido van Rossum43713e52000-02-29 13:59:29 +00002211 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002212 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002213
Martin v. Löwisa9656492003-03-30 08:44:58 +00002214#ifdef WITH_THREAD
Neal Norwitz12e22172003-03-03 21:16:39 +00002215 if (!self && !tcl_lock) {
2216 /* We don't have the Tcl lock since Tcl is threaded. */
2217 PyErr_SetString(PyExc_RuntimeError,
2218 "_tkinter.deletefilehandler not supported "
2219 "for threaded Tcl");
2220 return NULL;
2221 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002222#endif
Neal Norwitz12e22172003-03-03 21:16:39 +00002223
2224 if (self) {
2225 CHECK_TCL_APPARTMENT;
2226 }
2227
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002228 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002229 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002230 return NULL;
2231
Guido van Rossuma80649b2000-03-28 20:07:05 +00002232 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002233
Barry Warsawfa701a81997-01-16 00:15:11 +00002234 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002235 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002236 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002237 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002238 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002239 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002240}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002241#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002242
Barry Warsawfa701a81997-01-16 00:15:11 +00002243
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002244/**** Tktt Object (timer token) ****/
2245
Jeremy Hylton938ace62002-07-17 16:30:39 +00002246static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002247
Guido van Rossum00d93061998-05-28 23:06:38 +00002248typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002249 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002250 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002251 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002252} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002253
2254static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002255Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002256{
Barry Warsawfa701a81997-01-16 00:15:11 +00002257 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002258 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002259
Guido van Rossum43713e52000-02-29 13:59:29 +00002260 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002261 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002262 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002263 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002264 v->token = NULL;
2265 }
2266 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002267 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002268 Py_DECREF(func);
2269 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002270 }
2271 Py_INCREF(Py_None);
2272 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002273}
2274
2275static PyMethodDef Tktt_methods[] =
2276{
Neal Norwitzb0493252002-03-31 14:44:22 +00002277 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002278 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002279};
2280
2281static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002282Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002283{
Barry Warsawfa701a81997-01-16 00:15:11 +00002284 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002285
Guido van Rossumb18618d2000-05-03 23:44:39 +00002286 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002287 if (v == NULL)
2288 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002289
Guido van Rossum00d93061998-05-28 23:06:38 +00002290 Py_INCREF(func);
2291 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002292 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002293
2294 /* Extra reference, deleted when called or when handler is deleted */
2295 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002296 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002297}
2298
2299static void
Fred Drake509d79a2000-07-08 04:04:38 +00002300Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002301{
Guido van Rossum00d93061998-05-28 23:06:38 +00002302 TkttObject *v = (TkttObject *)self;
2303 PyObject *func = v->func;
2304
2305 Py_XDECREF(func);
2306
Guido van Rossumb18618d2000-05-03 23:44:39 +00002307 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002308}
2309
Guido van Rossum597ac201998-05-12 14:36:19 +00002310static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002311Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002312{
Barry Warsawfa701a81997-01-16 00:15:11 +00002313 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002314 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002315
Tim Peters885d4572001-11-28 20:27:42 +00002316 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002317 v->func == NULL ? ", handler deleted" : "");
Walter Dörwald1ab83302007-05-18 17:15:44 +00002318 return PyUnicode_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002319}
2320
2321static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002322Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002323{
Barry Warsawfa701a81997-01-16 00:15:11 +00002324 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002325}
2326
2327static PyTypeObject Tktt_Type =
2328{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002329 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002330 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002331 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002332 0, /*tp_itemsize */
2333 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002334 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00002335 Tktt_GetAttr, /*tp_getattr */
2336 0, /*tp_setattr */
2337 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00002338 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002339 0, /*tp_as_number */
2340 0, /*tp_as_sequence */
2341 0, /*tp_as_mapping */
2342 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002343};
2344
Barry Warsawfa701a81997-01-16 00:15:11 +00002345
2346
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002347/** Timer Handler **/
2348
2349static void
Fred Drake509d79a2000-07-08 04:04:38 +00002350TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002351{
Guido van Rossum00d93061998-05-28 23:06:38 +00002352 TkttObject *v = (TkttObject *)clientData;
2353 PyObject *func = v->func;
2354 PyObject *res;
2355
2356 if (func == NULL)
2357 return;
2358
2359 v->func = NULL;
2360
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002361 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002362
2363 res = PyEval_CallObject(func, NULL);
2364 Py_DECREF(func);
2365 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002366
Barry Warsawfa701a81997-01-16 00:15:11 +00002367 if (res == NULL) {
2368 errorInCmd = 1;
2369 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2370 }
2371 else
2372 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002373
2374 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002375}
2376
2377static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002378Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002379{
Barry Warsawfa701a81997-01-16 00:15:11 +00002380 int milliseconds;
2381 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002382 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002383
Guido van Rossum2834b972000-10-06 16:58:26 +00002384 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2385 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002386 return NULL;
2387 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002388 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002389 return NULL;
2390 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002391
Martin v. Löwisa9656492003-03-30 08:44:58 +00002392#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002393 if (!self && !tcl_lock) {
2394 /* We don't have the Tcl lock since Tcl is threaded. */
2395 PyErr_SetString(PyExc_RuntimeError,
2396 "_tkinter.createtimerhandler not supported "
2397 "for threaded Tcl");
2398 return NULL;
2399 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002400#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002401
2402 if (self) {
2403 CHECK_TCL_APPARTMENT;
2404 }
2405
Guido van Rossum00d93061998-05-28 23:06:38 +00002406 v = Tktt_New(func);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002407 if (v) {
2408 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2409 (ClientData)v);
2410 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002411
Guido van Rossum00d93061998-05-28 23:06:38 +00002412 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002413}
2414
Barry Warsawfa701a81997-01-16 00:15:11 +00002415
Guido van Rossum18468821994-06-20 07:49:28 +00002416/** Event Loop **/
2417
Guido van Rossum18468821994-06-20 07:49:28 +00002418static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002419Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002420{
Barry Warsawfa701a81997-01-16 00:15:11 +00002421 int threshold = 0;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002422 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002423#ifdef WITH_THREAD
2424 PyThreadState *tstate = PyThreadState_Get();
2425#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002426
Guido van Rossum43713e52000-02-29 13:59:29 +00002427 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002428 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002429
Martin v. Löwisa9656492003-03-30 08:44:58 +00002430#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002431 if (!self && !tcl_lock) {
2432 /* We don't have the Tcl lock since Tcl is threaded. */
2433 PyErr_SetString(PyExc_RuntimeError,
2434 "_tkinter.mainloop not supported "
2435 "for threaded Tcl");
2436 return NULL;
2437 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002438#endif
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002439
2440 if (self) {
2441 CHECK_TCL_APPARTMENT;
2442 self->dispatching = 1;
2443 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002444
Barry Warsawfa701a81997-01-16 00:15:11 +00002445 quitMainLoop = 0;
2446 while (Tk_GetNumMainWindows() > threshold &&
2447 !quitMainLoop &&
2448 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002449 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002450 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002451
2452#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002453 if (self && self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002454 /* Allow other Python threads to run. */
2455 ENTER_TCL
2456 result = Tcl_DoOneEvent(0);
2457 LEAVE_TCL
2458 }
2459 else {
2460 Py_BEGIN_ALLOW_THREADS
2461 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2462 tcl_tstate = tstate;
2463 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2464 tcl_tstate = NULL;
2465 if(tcl_lock)PyThread_release_lock(tcl_lock);
2466 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002467 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002468 Py_END_ALLOW_THREADS
2469 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002470#else
2471 result = Tcl_DoOneEvent(0);
2472#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002473
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002474 if (PyErr_CheckSignals() != 0) {
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002475 if (self)
2476 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002477 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002478 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002479 if (result < 0)
2480 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002481 }
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002482 if (self)
2483 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002484 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002485
Barry Warsawfa701a81997-01-16 00:15:11 +00002486 if (errorInCmd) {
2487 errorInCmd = 0;
2488 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2489 excInCmd = valInCmd = trbInCmd = NULL;
2490 return NULL;
2491 }
2492 Py_INCREF(Py_None);
2493 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002494}
2495
2496static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002497Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002498{
Guido van Rossum35d43371997-08-02 00:09:09 +00002499 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002500 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002501
Guido van Rossum43713e52000-02-29 13:59:29 +00002502 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002503 return NULL;
2504
Guido van Rossum00d93061998-05-28 23:06:38 +00002505 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002506 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002507 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002508 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002509}
2510
2511static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002512Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002513{
2514
Guido van Rossum43713e52000-02-29 13:59:29 +00002515 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002516 return NULL;
2517
2518 quitMainLoop = 1;
2519 Py_INCREF(Py_None);
2520 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002521}
2522
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002523static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002524Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002525{
2526
Guido van Rossum43713e52000-02-29 13:59:29 +00002527 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002528 return NULL;
2529
2530 return PyInt_FromLong((long)Tkapp_Interp(self));
2531}
2532
David Aschere2b4b322004-02-18 05:59:53 +00002533static PyObject *
2534Tkapp_TkInit(PyObject *self, PyObject *args)
2535{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002536 static int has_failed;
David Aschere2b4b322004-02-18 05:59:53 +00002537 Tcl_Interp *interp = Tkapp_Interp(self);
Neal Norwitz44dbae82004-02-19 02:44:22 +00002538 Tk_Window main_window;
David Aschere2b4b322004-02-18 05:59:53 +00002539 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002540 int err;
Neal Norwitz44dbae82004-02-19 02:44:22 +00002541 main_window = Tk_MainWindow(interp);
David Aschere2b4b322004-02-18 05:59:53 +00002542
Thomas Wouters477c8d52006-05-27 19:21:47 +00002543 /* In all current versions of Tk (including 8.4.13), Tk_Init
2544 deadlocks on the second call when the first call failed.
2545 To avoid the deadlock, we just refuse the second call through
2546 a static variable. */
2547 if (has_failed) {
2548 PyErr_SetString(Tkinter_TclError,
2549 "Calling Tk_Init again after a previous call failed might deadlock");
2550 return NULL;
2551 }
2552
David Aschere2b4b322004-02-18 05:59:53 +00002553 /* We want to guard against calling Tk_Init() multiple times */
2554 CHECK_TCL_APPARTMENT;
2555 ENTER_TCL
2556 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2557 ENTER_OVERLAP
2558 if (err == TCL_ERROR) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002559 /* This sets an exception, but we cannot return right
2560 away because we need to exit the overlap first. */
2561 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002562 } else {
2563 _tk_exists = Tkapp_Result(self);
2564 }
2565 LEAVE_OVERLAP_TCL
2566 if (err == TCL_ERROR) {
2567 return NULL;
2568 }
2569 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2570 if (Tk_Init(interp) == TCL_ERROR) {
2571 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
Thomas Wouters477c8d52006-05-27 19:21:47 +00002572 has_failed = 1;
David Aschere2b4b322004-02-18 05:59:53 +00002573 return NULL;
2574 }
2575 }
2576 Py_INCREF(Py_None);
2577 return Py_None;
2578}
Barry Warsawfa701a81997-01-16 00:15:11 +00002579
Martin v. Löwisffad6332002-11-26 09:28:05 +00002580static PyObject *
2581Tkapp_WantObjects(PyObject *self, PyObject *args)
2582{
2583
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002584 int wantobjects = -1;
2585 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002586 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002587 if (wantobjects == -1)
2588 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002589 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002590
2591 Py_INCREF(Py_None);
2592 return Py_None;
2593}
2594
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002595static PyObject *
2596Tkapp_WillDispatch(PyObject *self, PyObject *args)
2597{
2598
2599 ((TkappObject*)self)->dispatching = 1;
2600
2601 Py_INCREF(Py_None);
2602 return Py_None;
2603}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002604
Barry Warsawfa701a81997-01-16 00:15:11 +00002605
Guido van Rossum18468821994-06-20 07:49:28 +00002606/**** Tkapp Method List ****/
2607
2608static PyMethodDef Tkapp_methods[] =
2609{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002610 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002611 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002612 {"call", Tkapp_Call, METH_VARARGS},
2613 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002614 {"eval", Tkapp_Eval, METH_VARARGS},
2615 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2616 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2617 {"record", Tkapp_Record, METH_VARARGS},
2618 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2619 {"setvar", Tkapp_SetVar, METH_VARARGS},
2620 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2621 {"getvar", Tkapp_GetVar, METH_VARARGS},
2622 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2623 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2624 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2625 {"getint", Tkapp_GetInt, METH_VARARGS},
2626 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2627 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2628 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2629 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2630 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2631 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2632 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2633 {"split", Tkapp_Split, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002634 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002635 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2636 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002637#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002638 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2639 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002640#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002641 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2642 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2643 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2644 {"quit", Tkapp_Quit, METH_VARARGS},
2645 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002646 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002647 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002648};
2649
Barry Warsawfa701a81997-01-16 00:15:11 +00002650
2651
Guido van Rossum18468821994-06-20 07:49:28 +00002652/**** Tkapp Type Methods ****/
2653
2654static void
Fred Drake509d79a2000-07-08 04:04:38 +00002655Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002656{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002657 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002658 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002659 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002660 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002661 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002662 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002663}
2664
2665static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002666Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002667{
Guido van Rossum35d43371997-08-02 00:09:09 +00002668 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002669}
2670
2671static PyTypeObject Tkapp_Type =
2672{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002673 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002674 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002675 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002676 0, /*tp_itemsize */
2677 Tkapp_Dealloc, /*tp_dealloc */
2678 0, /*tp_print */
2679 Tkapp_GetAttr, /*tp_getattr */
2680 0, /*tp_setattr */
2681 0, /*tp_compare */
2682 0, /*tp_repr */
2683 0, /*tp_as_number */
2684 0, /*tp_as_sequence */
2685 0, /*tp_as_mapping */
2686 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002687};
2688
Barry Warsawfa701a81997-01-16 00:15:11 +00002689
2690
Guido van Rossum18468821994-06-20 07:49:28 +00002691/**** Tkinter Module ****/
2692
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002693typedef struct {
2694 PyObject* tuple;
2695 int size; /* current size */
2696 int maxsize; /* allocated size */
2697} FlattenContext;
2698
2699static int
2700_bump(FlattenContext* context, int size)
2701{
Guido van Rossum2834b972000-10-06 16:58:26 +00002702 /* expand tuple to hold (at least) size new items.
2703 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002704
2705 int maxsize = context->maxsize * 2;
2706
2707 if (maxsize < context->size + size)
2708 maxsize = context->size + size;
2709
2710 context->maxsize = maxsize;
2711
Tim Peters4324aa32001-05-28 22:30:08 +00002712 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002713}
2714
2715static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002716_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002717{
2718 /* add tuple or list to argument tuple (recursively) */
2719
2720 int i, size;
2721
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002722 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002723 PyErr_SetString(PyExc_ValueError,
2724 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002725 return 0;
2726 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002727 size = PyList_GET_SIZE(item);
2728 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002729 if (context->size + size > context->maxsize &&
2730 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002731 return 0;
2732 /* copy items to output tuple */
2733 for (i = 0; i < size; i++) {
2734 PyObject *o = PyList_GET_ITEM(item, i);
2735 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002736 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002737 return 0;
2738 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002739 if (context->size + 1 > context->maxsize &&
2740 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002741 return 0;
2742 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002743 PyTuple_SET_ITEM(context->tuple,
2744 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002745 }
2746 }
2747 } else if (PyTuple_Check(item)) {
2748 /* same, for tuples */
2749 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002750 if (context->size + size > context->maxsize &&
2751 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002752 return 0;
2753 for (i = 0; i < size; i++) {
2754 PyObject *o = PyTuple_GET_ITEM(item, i);
2755 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002756 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002757 return 0;
2758 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002759 if (context->size + 1 > context->maxsize &&
2760 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002761 return 0;
2762 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002763 PyTuple_SET_ITEM(context->tuple,
2764 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002765 }
2766 }
2767 } else {
2768 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2769 return 0;
2770 }
2771 return 1;
2772}
2773
2774static PyObject *
2775Tkinter_Flatten(PyObject* self, PyObject* args)
2776{
2777 FlattenContext context;
2778 PyObject* item;
2779
2780 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2781 return NULL;
2782
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002783 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002784 if (context.maxsize <= 0)
2785 return PyTuple_New(0);
2786
2787 context.tuple = PyTuple_New(context.maxsize);
2788 if (!context.tuple)
2789 return NULL;
2790
2791 context.size = 0;
2792
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002793 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002794 return NULL;
2795
Tim Peters4324aa32001-05-28 22:30:08 +00002796 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002797 return NULL;
2798
2799 return context.tuple;
2800}
2801
Guido van Rossum18468821994-06-20 07:49:28 +00002802static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002803Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002804{
Barry Warsawfa701a81997-01-16 00:15:11 +00002805 char *screenName = NULL;
2806 char *baseName = NULL;
2807 char *className = NULL;
2808 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002809 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002810 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002811 int sync = 0; /* pass -sync to wish */
2812 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002813
Guido van Rossum35d43371997-08-02 00:09:09 +00002814 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002815 if (baseName != NULL)
2816 baseName++;
2817 else
2818 baseName = Py_GetProgramName();
2819 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002820
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002821 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002822 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002823 &interactive, &wantobjects, &wantTk,
2824 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00002825 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002826
Barry Warsawfa701a81997-01-16 00:15:11 +00002827 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002828 interactive, wantobjects, wantTk,
2829 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002830}
2831
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002832static PyObject *
2833Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2834{
2835 int new_val;
2836 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2837 return NULL;
2838 if (new_val < 0) {
2839 PyErr_SetString(PyExc_ValueError,
2840 "busywaitinterval must be >= 0");
2841 return NULL;
2842 }
2843 Tkinter_busywaitinterval = new_val;
2844 Py_INCREF(Py_None);
2845 return Py_None;
2846}
2847
2848static char setbusywaitinterval_doc[] =
2849"setbusywaitinterval(n) -> None\n\
2850\n\
2851Set the busy-wait interval in milliseconds between successive\n\
2852calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2853It should be set to a divisor of the maximum time between\n\
2854frames in an animation.";
2855
2856static PyObject *
2857Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2858{
2859 return PyInt_FromLong(Tkinter_busywaitinterval);
2860}
2861
2862static char getbusywaitinterval_doc[] =
2863"getbusywaitinterval() -> int\n\
2864\n\
2865Return the current busy-wait interval between successive\n\
2866calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2867
Guido van Rossum18468821994-06-20 07:49:28 +00002868static PyMethodDef moduleMethods[] =
2869{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002870 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2871 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002872#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002873 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2874 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002875#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002876 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2877 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2878 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2879 {"quit", Tkapp_Quit, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002880 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2881 setbusywaitinterval_doc},
2882 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2883 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00002884 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002885};
2886
Guido van Rossum7bf15641998-05-22 18:28:17 +00002887#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002888
2889static int stdin_ready = 0;
2890
Guido van Rossumad4db171998-06-13 13:56:28 +00002891#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002892static void
Fred Drake509d79a2000-07-08 04:04:38 +00002893MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002894{
2895 stdin_ready = 1;
2896}
Guido van Rossumad4db171998-06-13 13:56:28 +00002897#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002898
Martin v. Löwisa9656492003-03-30 08:44:58 +00002899#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002900static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002901#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002902
Guido van Rossum18468821994-06-20 07:49:28 +00002903static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002904EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002905{
Guido van Rossumad4db171998-06-13 13:56:28 +00002906#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002907 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002908#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002909#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002910 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002911#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002912 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002913 errorInCmd = 0;
2914#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002915 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002916 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002917#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002918 while (!errorInCmd && !stdin_ready) {
2919 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002920#ifdef MS_WINDOWS
2921 if (_kbhit()) {
2922 stdin_ready = 1;
2923 break;
2924 }
2925#endif
2926#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002927 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002928 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002929 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002930
Guido van Rossum00d93061998-05-28 23:06:38 +00002931 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002932
2933 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002934 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002935 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002936 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00002937 Py_END_ALLOW_THREADS
2938#else
2939 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002940#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002941
2942 if (result < 0)
2943 break;
2944 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002945#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002946 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002947#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002948 if (errorInCmd) {
2949 errorInCmd = 0;
2950 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2951 excInCmd = valInCmd = trbInCmd = NULL;
2952 PyErr_Print();
2953 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002954#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002955 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002956#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002957 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002958}
Guido van Rossum18468821994-06-20 07:49:28 +00002959
Guido van Rossum00d93061998-05-28 23:06:38 +00002960#endif
2961
Guido van Rossum7bf15641998-05-22 18:28:17 +00002962static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002963EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002964{
Guido van Rossum00d93061998-05-28 23:06:38 +00002965#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002966 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002967#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002968 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002969#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002970 PyOS_InputHook = EventHook;
2971 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002972#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002973}
2974
2975static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002976DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002977{
Guido van Rossum00d93061998-05-28 23:06:38 +00002978#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002979 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2980 PyOS_InputHook = NULL;
2981 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002982#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002983}
2984
Barry Warsawfa701a81997-01-16 00:15:11 +00002985
2986/* all errors will be checked in one fell swoop in init_tkinter() */
2987static void
Fred Drake509d79a2000-07-08 04:04:38 +00002988ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002989{
2990 PyObject *v = PyInt_FromLong(val);
2991 if (v) {
2992 PyDict_SetItemString(d, name, v);
2993 Py_DECREF(v);
2994 }
2995}
2996static void
Fred Drake509d79a2000-07-08 04:04:38 +00002997ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002998{
Martin v. Löwis4040fb82007-08-13 06:01:43 +00002999 PyObject *v = PyUnicode_FromString(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003000 if (v) {
3001 PyDict_SetItemString(d, name, v);
3002 Py_DECREF(v);
3003 }
3004}
3005
3006
Mark Hammond62b1ab12002-07-23 06:31:15 +00003007PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003008init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003009{
Barry Warsawfa701a81997-01-16 00:15:11 +00003010 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00003011
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00003012 Py_Type(&Tkapp_Type) = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00003013
3014#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003015 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003016#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003017
Barry Warsawfa701a81997-01-16 00:15:11 +00003018 m = Py_InitModule("_tkinter", moduleMethods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003019 if (m == NULL)
3020 return;
Guido van Rossum18468821994-06-20 07:49:28 +00003021
Barry Warsawfa701a81997-01-16 00:15:11 +00003022 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003023 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003024 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003025
Guido van Rossum35d43371997-08-02 00:09:09 +00003026 ins_long(d, "READABLE", TCL_READABLE);
3027 ins_long(d, "WRITABLE", TCL_WRITABLE);
3028 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3029 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3030 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3031 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3032 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3033 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3034 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003035 ins_string(d, "TK_VERSION", TK_VERSION);
3036 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003037
Guido van Rossum83551bf1997-09-13 00:44:23 +00003038 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003039
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00003040 Py_Type(&Tktt_Type) = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003041 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3042
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00003043 Py_Type(&PyTclObject_Type) = &PyType_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003044 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003045
3046#ifdef TK_AQUA
3047 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3048 * start waking up. Note that Tcl_FindExecutable will do this, this
3049 * code must be above it! The original warning from
3050 * tkMacOSXAppInit.c is copied below.
3051 *
3052 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3053 * Tcl interpreter for now. It probably should work to do this
3054 * in the other order, but for now it doesn't seem to.
3055 *
3056 */
3057 Tk_MacOSXSetupTkNotifier();
3058#endif
3059
3060
Guido van Rossume187b0e2000-03-27 21:46:29 +00003061 /* This helps the dynamic loader; in Unicode aware Tcl versions
3062 it also helps Tcl find its encodings. */
3063 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00003064
Barry Warsawfa701a81997-01-16 00:15:11 +00003065 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003066 return;
3067
Guido van Rossum43ff8681998-07-14 18:02:13 +00003068#if 0
3069 /* This was not a good idea; through <Destroy> bindings,
3070 Tcl_Finalize() may invoke Python code but at that point the
3071 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003072 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003073#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003074
Guido van Rossum18468821994-06-20 07:49:28 +00003075}