blob: c0b47c28f5407a032565076faebc5a2c598af998 [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;
Martin v. Löwis50fb8662007-08-13 05:41:41 +00001900 PyObject *self, *func, *arg, *res;
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++) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001917 PyObject *s = PyUnicode_FromString(argv[i + 1]);
Barry Warsawfa701a81997-01-16 00:15:11 +00001918 if (!s || PyTuple_SetItem(arg, i, s)) {
1919 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001920 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001921 }
1922 }
1923 res = PyEval_CallObject(func, arg);
1924 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001925
Barry Warsawfa701a81997-01-16 00:15:11 +00001926 if (res == NULL)
1927 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001928
Martin v. Löwis50fb8662007-08-13 05:41:41 +00001929 tres = AsObj(res);
1930 if (tres == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001931 Py_DECREF(res);
1932 return PythonCmd_Error(interp);
1933 }
Guido van Rossum2834b972000-10-06 16:58:26 +00001934 else {
Martin v. Löwis50fb8662007-08-13 05:41:41 +00001935 Tcl_SetObjResult(Tkapp_Interp(self), tres);
Guido van Rossum2834b972000-10-06 16:58:26 +00001936 rv = TCL_OK;
1937 }
1938
Barry Warsawfa701a81997-01-16 00:15:11 +00001939 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00001940
Guido van Rossum00d93061998-05-28 23:06:38 +00001941 LEAVE_PYTHON
1942
Guido van Rossum2834b972000-10-06 16:58:26 +00001943 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001944}
1945
1946static void
Fred Drake509d79a2000-07-08 04:04:38 +00001947PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001948{
Guido van Rossum00d93061998-05-28 23:06:38 +00001949 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1950
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001951 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001952 Py_XDECREF(data->self);
1953 Py_XDECREF(data->func);
1954 PyMem_DEL(data);
1955 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001956}
1957
Barry Warsawfa701a81997-01-16 00:15:11 +00001958
1959
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001960
1961TCL_DECLARE_MUTEX(command_mutex)
1962
1963typedef struct CommandEvent{
1964 Tcl_Event ev;
1965 Tcl_Interp* interp;
1966 char *name;
1967 int create;
1968 int *status;
1969 ClientData *data;
1970 Tcl_Condition done;
1971} CommandEvent;
1972
1973static int
1974Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001975{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001976 if (ev->create)
1977 *ev->status = Tcl_CreateCommand(
1978 ev->interp, ev->name, PythonCmd,
1979 ev->data, PythonCmdDelete) == NULL;
1980 else
1981 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
1982 Tcl_MutexLock(&command_mutex);
1983 Tcl_ConditionNotify(&ev->done);
1984 Tcl_MutexUnlock(&command_mutex);
1985 return 1;
1986}
1987
1988static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001989Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001990{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001991 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00001992 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001993 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001994 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001995 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001996
Guido van Rossum43713e52000-02-29 13:59:29 +00001997 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001998 return NULL;
1999 if (!PyCallable_Check(func)) {
2000 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002001 return NULL;
2002 }
Guido van Rossum18468821994-06-20 07:49:28 +00002003
Martin v. Löwisa9656492003-03-30 08:44:58 +00002004#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002005 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002006 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002007 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002008#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002009
Guido van Rossum00d93061998-05-28 23:06:38 +00002010 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002011 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002012 return PyErr_NoMemory();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002013 Py_INCREF(self);
2014 Py_INCREF(func);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002015 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002016 data->func = func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002017
2018 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2019 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2020 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2021 ev->interp = self->interp;
2022 ev->create = 1;
2023 ev->name = cmdName;
2024 ev->data = (ClientData)data;
2025 ev->status = &err;
2026 ev->done = NULL;
2027 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
2028 }
2029 else {
2030 ENTER_TCL
2031 err = Tcl_CreateCommand(
2032 Tkapp_Interp(self), cmdName, PythonCmd,
2033 (ClientData)data, PythonCmdDelete) == NULL;
2034 LEAVE_TCL
2035 }
2036 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002037 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002038 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002039 return NULL;
2040 }
Guido van Rossum18468821994-06-20 07:49:28 +00002041
Barry Warsawfa701a81997-01-16 00:15:11 +00002042 Py_INCREF(Py_None);
2043 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002044}
2045
Barry Warsawfa701a81997-01-16 00:15:11 +00002046
2047
Guido van Rossum18468821994-06-20 07:49:28 +00002048static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002049Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002050{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002051 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002052 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002053 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002054
Guido van Rossum43713e52000-02-29 13:59:29 +00002055 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002056 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002057 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2058 CommandEvent *ev;
2059 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2060 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2061 ev->interp = self->interp;
2062 ev->create = 0;
2063 ev->name = cmdName;
2064 ev->status = &err;
2065 ev->done = NULL;
2066 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done,
2067 &command_mutex);
2068 }
2069 else {
2070 ENTER_TCL
2071 err = Tcl_DeleteCommand(self->interp, cmdName);
2072 LEAVE_TCL
2073 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002074 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002075 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2076 return NULL;
2077 }
2078 Py_INCREF(Py_None);
2079 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002080}
2081
Barry Warsawfa701a81997-01-16 00:15:11 +00002082
2083
Guido van Rossum00d93061998-05-28 23:06:38 +00002084#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002085/** File Handler **/
2086
Guido van Rossum00d93061998-05-28 23:06:38 +00002087typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002088 PyObject *func;
2089 PyObject *file;
2090 int id;
2091 struct _fhcdata *next;
2092} FileHandler_ClientData;
2093
2094static FileHandler_ClientData *HeadFHCD;
2095
2096static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002097NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002098{
2099 FileHandler_ClientData *p;
2100 p = PyMem_NEW(FileHandler_ClientData, 1);
2101 if (p != NULL) {
2102 Py_XINCREF(func);
2103 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002104 p->func = func;
2105 p->file = file;
2106 p->id = id;
2107 p->next = HeadFHCD;
2108 HeadFHCD = p;
2109 }
2110 return p;
2111}
2112
2113static void
Fred Drake509d79a2000-07-08 04:04:38 +00002114DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002115{
2116 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002117
2118 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002119 while ((p = *pp) != NULL) {
2120 if (p->id == id) {
2121 *pp = p->next;
2122 Py_XDECREF(p->func);
2123 Py_XDECREF(p->file);
2124 PyMem_DEL(p);
2125 }
2126 else
2127 pp = &p->next;
2128 }
2129}
2130
Guido van Rossuma597dde1995-01-10 20:56:29 +00002131static void
Fred Drake509d79a2000-07-08 04:04:38 +00002132FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002133{
Guido van Rossum00d93061998-05-28 23:06:38 +00002134 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002135 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002136
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002137 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002138 func = data->func;
2139 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002140
Barry Warsawfa701a81997-01-16 00:15:11 +00002141 arg = Py_BuildValue("(Oi)", file, (long) mask);
2142 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002143 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002144
2145 if (res == NULL) {
2146 errorInCmd = 1;
2147 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2148 }
2149 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002150 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002151}
2152
Guido van Rossum18468821994-06-20 07:49:28 +00002153static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002154Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2155 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002156{
Guido van Rossum00d93061998-05-28 23:06:38 +00002157 FileHandler_ClientData *data;
2158 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002159 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002160
Guido van Rossum2834b972000-10-06 16:58:26 +00002161 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2162 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002163 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002164
Martin v. Löwisa9656492003-03-30 08:44:58 +00002165#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002166 if (!self && !tcl_lock) {
2167 /* We don't have the Tcl lock since Tcl is threaded. */
2168 PyErr_SetString(PyExc_RuntimeError,
2169 "_tkinter.createfilehandler not supported "
2170 "for threaded Tcl");
2171 return NULL;
2172 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002173#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002174
2175 if (self) {
2176 CHECK_TCL_APPARTMENT;
2177 }
2178
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002179 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002180 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002181 return NULL;
2182 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002183 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002184 return NULL;
2185 }
2186
Guido van Rossuma80649b2000-03-28 20:07:05 +00002187 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002188 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002189 return NULL;
2190
Barry Warsawfa701a81997-01-16 00:15:11 +00002191 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002192 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002193 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002194 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002195 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002196 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002197}
2198
2199static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002200Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002201{
Barry Warsawfa701a81997-01-16 00:15:11 +00002202 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002203 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002204
Guido van Rossum43713e52000-02-29 13:59:29 +00002205 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002206 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002207
Martin v. Löwisa9656492003-03-30 08:44:58 +00002208#ifdef WITH_THREAD
Neal Norwitz12e22172003-03-03 21:16:39 +00002209 if (!self && !tcl_lock) {
2210 /* We don't have the Tcl lock since Tcl is threaded. */
2211 PyErr_SetString(PyExc_RuntimeError,
2212 "_tkinter.deletefilehandler not supported "
2213 "for threaded Tcl");
2214 return NULL;
2215 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002216#endif
Neal Norwitz12e22172003-03-03 21:16:39 +00002217
2218 if (self) {
2219 CHECK_TCL_APPARTMENT;
2220 }
2221
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002222 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002223 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002224 return NULL;
2225
Guido van Rossuma80649b2000-03-28 20:07:05 +00002226 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002227
Barry Warsawfa701a81997-01-16 00:15:11 +00002228 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002229 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002230 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002231 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002232 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002233 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002234}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002235#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002236
Barry Warsawfa701a81997-01-16 00:15:11 +00002237
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002238/**** Tktt Object (timer token) ****/
2239
Jeremy Hylton938ace62002-07-17 16:30:39 +00002240static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002241
Guido van Rossum00d93061998-05-28 23:06:38 +00002242typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002243 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002244 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002245 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002246} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002247
2248static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002249Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002250{
Barry Warsawfa701a81997-01-16 00:15:11 +00002251 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002252 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002253
Guido van Rossum43713e52000-02-29 13:59:29 +00002254 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002255 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002256 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002257 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002258 v->token = NULL;
2259 }
2260 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002261 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002262 Py_DECREF(func);
2263 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002264 }
2265 Py_INCREF(Py_None);
2266 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002267}
2268
2269static PyMethodDef Tktt_methods[] =
2270{
Neal Norwitzb0493252002-03-31 14:44:22 +00002271 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002272 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002273};
2274
2275static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002276Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002277{
Barry Warsawfa701a81997-01-16 00:15:11 +00002278 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002279
Guido van Rossumb18618d2000-05-03 23:44:39 +00002280 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002281 if (v == NULL)
2282 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002283
Guido van Rossum00d93061998-05-28 23:06:38 +00002284 Py_INCREF(func);
2285 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002286 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002287
2288 /* Extra reference, deleted when called or when handler is deleted */
2289 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002290 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002291}
2292
2293static void
Fred Drake509d79a2000-07-08 04:04:38 +00002294Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002295{
Guido van Rossum00d93061998-05-28 23:06:38 +00002296 TkttObject *v = (TkttObject *)self;
2297 PyObject *func = v->func;
2298
2299 Py_XDECREF(func);
2300
Guido van Rossumb18618d2000-05-03 23:44:39 +00002301 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002302}
2303
Guido van Rossum597ac201998-05-12 14:36:19 +00002304static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002305Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002306{
Barry Warsawfa701a81997-01-16 00:15:11 +00002307 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002308 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002309
Tim Peters885d4572001-11-28 20:27:42 +00002310 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002311 v->func == NULL ? ", handler deleted" : "");
Walter Dörwald1ab83302007-05-18 17:15:44 +00002312 return PyUnicode_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002313}
2314
2315static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002316Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002317{
Barry Warsawfa701a81997-01-16 00:15:11 +00002318 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002319}
2320
2321static PyTypeObject Tktt_Type =
2322{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002323 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002324 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002325 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002326 0, /*tp_itemsize */
2327 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002328 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00002329 Tktt_GetAttr, /*tp_getattr */
2330 0, /*tp_setattr */
2331 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00002332 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002333 0, /*tp_as_number */
2334 0, /*tp_as_sequence */
2335 0, /*tp_as_mapping */
2336 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002337};
2338
Barry Warsawfa701a81997-01-16 00:15:11 +00002339
2340
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002341/** Timer Handler **/
2342
2343static void
Fred Drake509d79a2000-07-08 04:04:38 +00002344TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002345{
Guido van Rossum00d93061998-05-28 23:06:38 +00002346 TkttObject *v = (TkttObject *)clientData;
2347 PyObject *func = v->func;
2348 PyObject *res;
2349
2350 if (func == NULL)
2351 return;
2352
2353 v->func = NULL;
2354
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002355 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002356
2357 res = PyEval_CallObject(func, NULL);
2358 Py_DECREF(func);
2359 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002360
Barry Warsawfa701a81997-01-16 00:15:11 +00002361 if (res == NULL) {
2362 errorInCmd = 1;
2363 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2364 }
2365 else
2366 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002367
2368 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002369}
2370
2371static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002372Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002373{
Barry Warsawfa701a81997-01-16 00:15:11 +00002374 int milliseconds;
2375 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002376 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002377
Guido van Rossum2834b972000-10-06 16:58:26 +00002378 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2379 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002380 return NULL;
2381 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002382 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002383 return NULL;
2384 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002385
Martin v. Löwisa9656492003-03-30 08:44:58 +00002386#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002387 if (!self && !tcl_lock) {
2388 /* We don't have the Tcl lock since Tcl is threaded. */
2389 PyErr_SetString(PyExc_RuntimeError,
2390 "_tkinter.createtimerhandler not supported "
2391 "for threaded Tcl");
2392 return NULL;
2393 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002394#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002395
2396 if (self) {
2397 CHECK_TCL_APPARTMENT;
2398 }
2399
Guido van Rossum00d93061998-05-28 23:06:38 +00002400 v = Tktt_New(func);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002401 if (v) {
2402 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2403 (ClientData)v);
2404 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002405
Guido van Rossum00d93061998-05-28 23:06:38 +00002406 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002407}
2408
Barry Warsawfa701a81997-01-16 00:15:11 +00002409
Guido van Rossum18468821994-06-20 07:49:28 +00002410/** Event Loop **/
2411
Guido van Rossum18468821994-06-20 07:49:28 +00002412static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002413Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002414{
Barry Warsawfa701a81997-01-16 00:15:11 +00002415 int threshold = 0;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002416 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002417#ifdef WITH_THREAD
2418 PyThreadState *tstate = PyThreadState_Get();
2419#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002420
Guido van Rossum43713e52000-02-29 13:59:29 +00002421 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002422 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002423
Martin v. Löwisa9656492003-03-30 08:44:58 +00002424#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002425 if (!self && !tcl_lock) {
2426 /* We don't have the Tcl lock since Tcl is threaded. */
2427 PyErr_SetString(PyExc_RuntimeError,
2428 "_tkinter.mainloop not supported "
2429 "for threaded Tcl");
2430 return NULL;
2431 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002432#endif
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002433
2434 if (self) {
2435 CHECK_TCL_APPARTMENT;
2436 self->dispatching = 1;
2437 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002438
Barry Warsawfa701a81997-01-16 00:15:11 +00002439 quitMainLoop = 0;
2440 while (Tk_GetNumMainWindows() > threshold &&
2441 !quitMainLoop &&
2442 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002443 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002444 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002445
2446#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002447 if (self && self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002448 /* Allow other Python threads to run. */
2449 ENTER_TCL
2450 result = Tcl_DoOneEvent(0);
2451 LEAVE_TCL
2452 }
2453 else {
2454 Py_BEGIN_ALLOW_THREADS
2455 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2456 tcl_tstate = tstate;
2457 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2458 tcl_tstate = NULL;
2459 if(tcl_lock)PyThread_release_lock(tcl_lock);
2460 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002461 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002462 Py_END_ALLOW_THREADS
2463 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002464#else
2465 result = Tcl_DoOneEvent(0);
2466#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002467
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002468 if (PyErr_CheckSignals() != 0) {
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002469 if (self)
2470 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002471 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002472 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002473 if (result < 0)
2474 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002475 }
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002476 if (self)
2477 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002478 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002479
Barry Warsawfa701a81997-01-16 00:15:11 +00002480 if (errorInCmd) {
2481 errorInCmd = 0;
2482 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2483 excInCmd = valInCmd = trbInCmd = NULL;
2484 return NULL;
2485 }
2486 Py_INCREF(Py_None);
2487 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002488}
2489
2490static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002491Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002492{
Guido van Rossum35d43371997-08-02 00:09:09 +00002493 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002494 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002495
Guido van Rossum43713e52000-02-29 13:59:29 +00002496 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002497 return NULL;
2498
Guido van Rossum00d93061998-05-28 23:06:38 +00002499 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002500 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002501 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002502 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002503}
2504
2505static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002506Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002507{
2508
Guido van Rossum43713e52000-02-29 13:59:29 +00002509 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002510 return NULL;
2511
2512 quitMainLoop = 1;
2513 Py_INCREF(Py_None);
2514 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002515}
2516
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002517static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002518Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002519{
2520
Guido van Rossum43713e52000-02-29 13:59:29 +00002521 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002522 return NULL;
2523
2524 return PyInt_FromLong((long)Tkapp_Interp(self));
2525}
2526
David Aschere2b4b322004-02-18 05:59:53 +00002527static PyObject *
2528Tkapp_TkInit(PyObject *self, PyObject *args)
2529{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002530 static int has_failed;
David Aschere2b4b322004-02-18 05:59:53 +00002531 Tcl_Interp *interp = Tkapp_Interp(self);
Neal Norwitz44dbae82004-02-19 02:44:22 +00002532 Tk_Window main_window;
David Aschere2b4b322004-02-18 05:59:53 +00002533 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002534 int err;
Neal Norwitz44dbae82004-02-19 02:44:22 +00002535 main_window = Tk_MainWindow(interp);
David Aschere2b4b322004-02-18 05:59:53 +00002536
Thomas Wouters477c8d52006-05-27 19:21:47 +00002537 /* In all current versions of Tk (including 8.4.13), Tk_Init
2538 deadlocks on the second call when the first call failed.
2539 To avoid the deadlock, we just refuse the second call through
2540 a static variable. */
2541 if (has_failed) {
2542 PyErr_SetString(Tkinter_TclError,
2543 "Calling Tk_Init again after a previous call failed might deadlock");
2544 return NULL;
2545 }
2546
David Aschere2b4b322004-02-18 05:59:53 +00002547 /* We want to guard against calling Tk_Init() multiple times */
2548 CHECK_TCL_APPARTMENT;
2549 ENTER_TCL
2550 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2551 ENTER_OVERLAP
2552 if (err == TCL_ERROR) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002553 /* This sets an exception, but we cannot return right
2554 away because we need to exit the overlap first. */
2555 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002556 } else {
2557 _tk_exists = Tkapp_Result(self);
2558 }
2559 LEAVE_OVERLAP_TCL
2560 if (err == TCL_ERROR) {
2561 return NULL;
2562 }
2563 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2564 if (Tk_Init(interp) == TCL_ERROR) {
2565 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
Thomas Wouters477c8d52006-05-27 19:21:47 +00002566 has_failed = 1;
David Aschere2b4b322004-02-18 05:59:53 +00002567 return NULL;
2568 }
2569 }
2570 Py_INCREF(Py_None);
2571 return Py_None;
2572}
Barry Warsawfa701a81997-01-16 00:15:11 +00002573
Martin v. Löwisffad6332002-11-26 09:28:05 +00002574static PyObject *
2575Tkapp_WantObjects(PyObject *self, PyObject *args)
2576{
2577
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002578 int wantobjects = -1;
2579 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002580 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002581 if (wantobjects == -1)
2582 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002583 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002584
2585 Py_INCREF(Py_None);
2586 return Py_None;
2587}
2588
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002589static PyObject *
2590Tkapp_WillDispatch(PyObject *self, PyObject *args)
2591{
2592
2593 ((TkappObject*)self)->dispatching = 1;
2594
2595 Py_INCREF(Py_None);
2596 return Py_None;
2597}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002598
Barry Warsawfa701a81997-01-16 00:15:11 +00002599
Guido van Rossum18468821994-06-20 07:49:28 +00002600/**** Tkapp Method List ****/
2601
2602static PyMethodDef Tkapp_methods[] =
2603{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002604 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002605 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002606 {"call", Tkapp_Call, METH_VARARGS},
2607 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002608 {"eval", Tkapp_Eval, METH_VARARGS},
2609 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2610 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2611 {"record", Tkapp_Record, METH_VARARGS},
2612 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2613 {"setvar", Tkapp_SetVar, METH_VARARGS},
2614 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2615 {"getvar", Tkapp_GetVar, METH_VARARGS},
2616 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2617 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2618 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2619 {"getint", Tkapp_GetInt, METH_VARARGS},
2620 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2621 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2622 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2623 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2624 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2625 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2626 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2627 {"split", Tkapp_Split, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002628 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002629 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2630 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002631#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002632 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2633 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002634#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002635 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2636 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2637 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2638 {"quit", Tkapp_Quit, METH_VARARGS},
2639 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002640 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002641 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002642};
2643
Barry Warsawfa701a81997-01-16 00:15:11 +00002644
2645
Guido van Rossum18468821994-06-20 07:49:28 +00002646/**** Tkapp Type Methods ****/
2647
2648static void
Fred Drake509d79a2000-07-08 04:04:38 +00002649Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002650{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002651 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002652 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002653 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002654 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002655 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002656 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002657}
2658
2659static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002660Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002661{
Guido van Rossum35d43371997-08-02 00:09:09 +00002662 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002663}
2664
2665static PyTypeObject Tkapp_Type =
2666{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002667 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002668 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002669 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002670 0, /*tp_itemsize */
2671 Tkapp_Dealloc, /*tp_dealloc */
2672 0, /*tp_print */
2673 Tkapp_GetAttr, /*tp_getattr */
2674 0, /*tp_setattr */
2675 0, /*tp_compare */
2676 0, /*tp_repr */
2677 0, /*tp_as_number */
2678 0, /*tp_as_sequence */
2679 0, /*tp_as_mapping */
2680 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002681};
2682
Barry Warsawfa701a81997-01-16 00:15:11 +00002683
2684
Guido van Rossum18468821994-06-20 07:49:28 +00002685/**** Tkinter Module ****/
2686
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002687typedef struct {
2688 PyObject* tuple;
2689 int size; /* current size */
2690 int maxsize; /* allocated size */
2691} FlattenContext;
2692
2693static int
2694_bump(FlattenContext* context, int size)
2695{
Guido van Rossum2834b972000-10-06 16:58:26 +00002696 /* expand tuple to hold (at least) size new items.
2697 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002698
2699 int maxsize = context->maxsize * 2;
2700
2701 if (maxsize < context->size + size)
2702 maxsize = context->size + size;
2703
2704 context->maxsize = maxsize;
2705
Tim Peters4324aa32001-05-28 22:30:08 +00002706 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002707}
2708
2709static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002710_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002711{
2712 /* add tuple or list to argument tuple (recursively) */
2713
2714 int i, size;
2715
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002716 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002717 PyErr_SetString(PyExc_ValueError,
2718 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002719 return 0;
2720 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002721 size = PyList_GET_SIZE(item);
2722 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002723 if (context->size + size > context->maxsize &&
2724 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002725 return 0;
2726 /* copy items to output tuple */
2727 for (i = 0; i < size; i++) {
2728 PyObject *o = PyList_GET_ITEM(item, i);
2729 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002730 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002731 return 0;
2732 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002733 if (context->size + 1 > context->maxsize &&
2734 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002735 return 0;
2736 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002737 PyTuple_SET_ITEM(context->tuple,
2738 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002739 }
2740 }
2741 } else if (PyTuple_Check(item)) {
2742 /* same, for tuples */
2743 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002744 if (context->size + size > context->maxsize &&
2745 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002746 return 0;
2747 for (i = 0; i < size; i++) {
2748 PyObject *o = PyTuple_GET_ITEM(item, i);
2749 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002750 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002751 return 0;
2752 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002753 if (context->size + 1 > context->maxsize &&
2754 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002755 return 0;
2756 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002757 PyTuple_SET_ITEM(context->tuple,
2758 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002759 }
2760 }
2761 } else {
2762 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2763 return 0;
2764 }
2765 return 1;
2766}
2767
2768static PyObject *
2769Tkinter_Flatten(PyObject* self, PyObject* args)
2770{
2771 FlattenContext context;
2772 PyObject* item;
2773
2774 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2775 return NULL;
2776
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002777 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002778 if (context.maxsize <= 0)
2779 return PyTuple_New(0);
2780
2781 context.tuple = PyTuple_New(context.maxsize);
2782 if (!context.tuple)
2783 return NULL;
2784
2785 context.size = 0;
2786
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002787 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002788 return NULL;
2789
Tim Peters4324aa32001-05-28 22:30:08 +00002790 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002791 return NULL;
2792
2793 return context.tuple;
2794}
2795
Guido van Rossum18468821994-06-20 07:49:28 +00002796static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002797Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002798{
Barry Warsawfa701a81997-01-16 00:15:11 +00002799 char *screenName = NULL;
2800 char *baseName = NULL;
2801 char *className = NULL;
2802 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002803 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002804 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002805 int sync = 0; /* pass -sync to wish */
2806 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002807
Guido van Rossum35d43371997-08-02 00:09:09 +00002808 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002809 if (baseName != NULL)
2810 baseName++;
2811 else
2812 baseName = Py_GetProgramName();
2813 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002814
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002815 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002816 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002817 &interactive, &wantobjects, &wantTk,
2818 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00002819 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002820
Barry Warsawfa701a81997-01-16 00:15:11 +00002821 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002822 interactive, wantobjects, wantTk,
2823 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002824}
2825
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002826static PyObject *
2827Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2828{
2829 int new_val;
2830 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2831 return NULL;
2832 if (new_val < 0) {
2833 PyErr_SetString(PyExc_ValueError,
2834 "busywaitinterval must be >= 0");
2835 return NULL;
2836 }
2837 Tkinter_busywaitinterval = new_val;
2838 Py_INCREF(Py_None);
2839 return Py_None;
2840}
2841
2842static char setbusywaitinterval_doc[] =
2843"setbusywaitinterval(n) -> None\n\
2844\n\
2845Set the busy-wait interval in milliseconds between successive\n\
2846calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2847It should be set to a divisor of the maximum time between\n\
2848frames in an animation.";
2849
2850static PyObject *
2851Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2852{
2853 return PyInt_FromLong(Tkinter_busywaitinterval);
2854}
2855
2856static char getbusywaitinterval_doc[] =
2857"getbusywaitinterval() -> int\n\
2858\n\
2859Return the current busy-wait interval between successive\n\
2860calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2861
Guido van Rossum18468821994-06-20 07:49:28 +00002862static PyMethodDef moduleMethods[] =
2863{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002864 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2865 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002866#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002867 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2868 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002869#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002870 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2871 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2872 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2873 {"quit", Tkapp_Quit, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002874 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2875 setbusywaitinterval_doc},
2876 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2877 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00002878 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002879};
2880
Guido van Rossum7bf15641998-05-22 18:28:17 +00002881#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002882
2883static int stdin_ready = 0;
2884
Guido van Rossumad4db171998-06-13 13:56:28 +00002885#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002886static void
Fred Drake509d79a2000-07-08 04:04:38 +00002887MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002888{
2889 stdin_ready = 1;
2890}
Guido van Rossumad4db171998-06-13 13:56:28 +00002891#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002892
Martin v. Löwisa9656492003-03-30 08:44:58 +00002893#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002894static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002895#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002896
Guido van Rossum18468821994-06-20 07:49:28 +00002897static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002898EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002899{
Guido van Rossumad4db171998-06-13 13:56:28 +00002900#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002901 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002902#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002903#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002904 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002905#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002906 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002907 errorInCmd = 0;
2908#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002909 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002910 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002911#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002912 while (!errorInCmd && !stdin_ready) {
2913 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002914#ifdef MS_WINDOWS
2915 if (_kbhit()) {
2916 stdin_ready = 1;
2917 break;
2918 }
2919#endif
2920#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002921 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002922 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002923 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002924
Guido van Rossum00d93061998-05-28 23:06:38 +00002925 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002926
2927 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002928 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002929 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002930 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00002931 Py_END_ALLOW_THREADS
2932#else
2933 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002934#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002935
2936 if (result < 0)
2937 break;
2938 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002939#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002940 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002941#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002942 if (errorInCmd) {
2943 errorInCmd = 0;
2944 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2945 excInCmd = valInCmd = trbInCmd = NULL;
2946 PyErr_Print();
2947 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002948#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002949 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002950#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002951 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002952}
Guido van Rossum18468821994-06-20 07:49:28 +00002953
Guido van Rossum00d93061998-05-28 23:06:38 +00002954#endif
2955
Guido van Rossum7bf15641998-05-22 18:28:17 +00002956static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002957EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002958{
Guido van Rossum00d93061998-05-28 23:06:38 +00002959#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002960 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002961#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002962 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002963#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002964 PyOS_InputHook = EventHook;
2965 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002966#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002967}
2968
2969static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002970DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002971{
Guido van Rossum00d93061998-05-28 23:06:38 +00002972#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002973 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2974 PyOS_InputHook = NULL;
2975 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002976#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002977}
2978
Barry Warsawfa701a81997-01-16 00:15:11 +00002979
2980/* all errors will be checked in one fell swoop in init_tkinter() */
2981static void
Fred Drake509d79a2000-07-08 04:04:38 +00002982ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002983{
2984 PyObject *v = PyInt_FromLong(val);
2985 if (v) {
2986 PyDict_SetItemString(d, name, v);
2987 Py_DECREF(v);
2988 }
2989}
2990static void
Fred Drake509d79a2000-07-08 04:04:38 +00002991ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002992{
Martin v. Löwis4040fb82007-08-13 06:01:43 +00002993 PyObject *v = PyUnicode_FromString(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00002994 if (v) {
2995 PyDict_SetItemString(d, name, v);
2996 Py_DECREF(v);
2997 }
2998}
2999
3000
Mark Hammond62b1ab12002-07-23 06:31:15 +00003001PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003002init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003003{
Barry Warsawfa701a81997-01-16 00:15:11 +00003004 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00003005
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00003006 Py_Type(&Tkapp_Type) = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00003007
3008#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003009 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003010#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003011
Barry Warsawfa701a81997-01-16 00:15:11 +00003012 m = Py_InitModule("_tkinter", moduleMethods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003013 if (m == NULL)
3014 return;
Guido van Rossum18468821994-06-20 07:49:28 +00003015
Barry Warsawfa701a81997-01-16 00:15:11 +00003016 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003017 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003018 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003019
Guido van Rossum35d43371997-08-02 00:09:09 +00003020 ins_long(d, "READABLE", TCL_READABLE);
3021 ins_long(d, "WRITABLE", TCL_WRITABLE);
3022 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3023 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3024 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3025 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3026 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3027 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3028 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003029 ins_string(d, "TK_VERSION", TK_VERSION);
3030 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003031
Guido van Rossum83551bf1997-09-13 00:44:23 +00003032 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003033
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00003034 Py_Type(&Tktt_Type) = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003035 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3036
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00003037 Py_Type(&PyTclObject_Type) = &PyType_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003038 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003039
3040#ifdef TK_AQUA
3041 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3042 * start waking up. Note that Tcl_FindExecutable will do this, this
3043 * code must be above it! The original warning from
3044 * tkMacOSXAppInit.c is copied below.
3045 *
3046 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3047 * Tcl interpreter for now. It probably should work to do this
3048 * in the other order, but for now it doesn't seem to.
3049 *
3050 */
3051 Tk_MacOSXSetupTkNotifier();
3052#endif
3053
3054
Guido van Rossume187b0e2000-03-27 21:46:29 +00003055 /* This helps the dynamic loader; in Unicode aware Tcl versions
3056 it also helps Tcl find its encodings. */
3057 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00003058
Barry Warsawfa701a81997-01-16 00:15:11 +00003059 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003060 return;
3061
Guido van Rossum43ff8681998-07-14 18:02:13 +00003062#if 0
3063 /* This was not a good idea; through <Destroy> bindings,
3064 Tcl_Finalize() may invoke Python code but at that point the
3065 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003066 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003067#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003068
Guido van Rossum18468821994-06-20 07:49:28 +00003069}