blob: fe568fad073d3ab89f5179148a4dffb5ed10b0a2 [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
Guido van Rossum845547d1996-06-26 18:26:04 +00003
4 All Rights Reserved
5
Guido van Rossum845547d1996-06-26 18:26:04 +00006******************************************************************/
7
8/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +00009
Guido van Rossum7ffa7611996-08-13 21:10:16 +000010/* TCL/TK VERSION INFO:
11
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000012 Only Tcl/Tk 8.2 and later are supported. Older versions are not
13 supported. (Use Python 2.2 if you cannot upgrade your Tcl/Tk
Guido van Rossuma80649b2000-03-28 20:07:05 +000014 libraries.)
15*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000016
Guido van Rossuma80649b2000-03-28 20:07:05 +000017/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000018
Guido van Rossum212643f1998-04-29 16:22:14 +000019 - Register a new Tcl type, "Python callable", which can be called more
20 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
21
Guido van Rossum7ffa7611996-08-13 21:10:16 +000022*/
23
Guido van Rossum35d43371997-08-02 00:09:09 +000024
Guido van Rossum9722ad81995-09-22 23:49:28 +000025#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000026#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000027
Guido van Rossum00d93061998-05-28 23:06:38 +000028#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000029#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000030#endif
31
Guido van Rossum2a5119b1998-05-29 01:28:40 +000032#ifdef MS_WINDOWS
33#include <windows.h>
34#endif
35
Martin v. Löwis39195712003-01-04 00:33:13 +000036/* Allow using this code in Python 2.[12] */
37#ifndef PyDoc_STRVAR
Martin v. Löwiscd9a8b62003-01-21 21:52:57 +000038#define PyDoc_STRVAR(name,str) static char name[] = str
Martin v. Löwis39195712003-01-04 00:33:13 +000039#endif
40
41#ifndef PyMODINIT_FUNC
Martin v. Löwis3a57d9d2003-01-04 08:54:59 +000042#define PyMODINIT_FUNC void
Martin v. Löwis39195712003-01-04 00:33:13 +000043#endif
44
Martin v. Löwis52ae6f62003-03-30 08:26:04 +000045#ifndef PyBool_Check
46#define PyBool_Check(o) 0
47#define PyBool_FromLong PyInt_FromLong
48#endif
49
Martin v. Löwis71e25a02002-10-01 18:08:06 +000050/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
51 making _tkinter correct for this API means to break earlier
52 versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
53 earlier versions. Once Tcl releases before 8.4 don't need to be supported
54 anymore, this should go. */
55#define USE_COMPAT_CONST
56
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000057/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
58 it always; if Tcl is not threaded, the thread functions in
59 Tcl are empty. */
60#define TCL_THREADS
61
Jack Jansencb852442001-12-09 23:15:56 +000062#ifdef TK_FRAMEWORK
63#include <Tcl/tcl.h>
64#include <Tk/tk.h>
65#else
Guido van Rossum18468821994-06-20 07:49:28 +000066#include <tcl.h>
67#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000068#endif
Guido van Rossum18468821994-06-20 07:49:28 +000069
Jason Tishlerbbe89612002-12-31 20:30:46 +000070/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
Martin v. Löwis5b177f12002-12-30 18:14:15 +000071#ifndef CONST84_RETURN
72#define CONST84_RETURN
Jason Tishlerbbe89612002-12-31 20:30:46 +000073#undef CONST
Martin v. Löwis5b177f12002-12-30 18:14:15 +000074#define CONST
75#endif
76
Guido van Rossum3e819a71997-08-01 19:29:02 +000077#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
78
Martin v. Löwis6bfa2e62002-10-01 17:48:31 +000079#if TKMAJORMINOR < 8002
80#error "Tk older than 8.2 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000081#endif
82
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000083/* Unicode conversion assumes that Tcl_UniChar is two bytes.
84 We cannot test this directly, so we test UTF-8 size instead,
85 expecting that TCL_UTF_MAX is changed if Tcl ever supports
Martin v. Löwis6f29ff32003-04-16 20:34:55 +000086 either UTF-16 or UCS-4.
87 Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for
88 Tcl_Unichar. This is also ok as long as Python uses UCS-4,
89 as well.
90*/
91#if TCL_UTF_MAX != 3 && !(defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==6)
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000092#error "unsupported Tcl configuration"
93#endif
94
Jack Janseneddc1442003-11-20 01:44:59 +000095#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
Guido van Rossum0d2390c1997-08-14 19:57:07 +000096#define HAVE_CREATEFILEHANDLER
97#endif
98
Guido van Rossum00d93061998-05-28 23:06:38 +000099#ifdef HAVE_CREATEFILEHANDLER
100
Neal Norwitzd948a432006-01-08 01:08:55 +0000101/* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere
102 with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */
103#ifndef TCL_UNIX_FD
104# ifdef TCL_WIN_SOCKET
105# define TCL_UNIX_FD (! TCL_WIN_SOCKET)
106# else
107# define TCL_UNIX_FD 1
108# endif
109#endif
110
Guido van Rossum00d93061998-05-28 23:06:38 +0000111/* Tcl_CreateFileHandler() changed several times; these macros deal with the
112 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
113 Unix, only because Jack added it back); when available on Windows, it only
114 applies to sockets. */
115
Guido van Rossum7bf15641998-05-22 18:28:17 +0000116#ifdef MS_WINDOWS
117#define FHANDLETYPE TCL_WIN_SOCKET
118#else
119#define FHANDLETYPE TCL_UNIX_FD
120#endif
121
Guido van Rossum00d93061998-05-28 23:06:38 +0000122/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
123 which uses this to handle Tcl events while the user is typing commands. */
124
125#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000126#define WAIT_FOR_STDIN
127#endif
128
Guido van Rossum00d93061998-05-28 23:06:38 +0000129#endif /* HAVE_CREATEFILEHANDLER */
130
Guido van Rossumad4db171998-06-13 13:56:28 +0000131#ifdef MS_WINDOWS
132#include <conio.h>
133#define WAIT_FOR_STDIN
134#endif
135
Guido van Rossum00d93061998-05-28 23:06:38 +0000136#ifdef WITH_THREAD
137
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000138/* The threading situation is complicated. Tcl is not thread-safe, except
139 when configured with --enable-threads.
Guido van Rossum00d93061998-05-28 23:06:38 +0000140 So we need to use a lock around all uses of Tcl. Previously, the Python
141 interpreter lock was used for this. However, this causes problems when
142 other Python threads need to run while Tcl is blocked waiting for events.
143
144 To solve this problem, a separate lock for Tcl is introduced. Holding it
145 is incompatible with holding Python's interpreter lock. The following four
146 macros manipulate both locks together.
147
148 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
149 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
150 that could call an event handler, or otherwise affect the state of a Tcl
151 interpreter. These assume that the surrounding code has the Python
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000152 interpreter lock; inside the brackets, the Python interpreter lock has been
Guido van Rossum00d93061998-05-28 23:06:38 +0000153 released and the lock for Tcl has been acquired.
154
Guido van Rossum5e977831998-06-15 14:03:52 +0000155 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
156 (For example, when transferring data from the Tcl interpreter result to a
157 Python string object.) This can be done by using different macros to close
158 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
159 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
160 releases the Tcl lock.
161
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000162 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000163 handlers when the handler needs to use Python. Such event handlers are
164 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000165 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000166 the Python interpreter lock, restoring the appropriate thread state, and
167 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
168 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000169 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000170
171 These locks expand to several statements and brackets; they should not be
172 used in branches of if statements and the like.
173
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000174 If Tcl is threaded, this approach won't work anymore. The Tcl interpreter is
175 only valid in the thread that created it, and all Tk activity must happen in this
176 thread, also. That means that the mainloop must be invoked in the thread that
177 created the interpreter. Invoking commands from other threads is possible;
178 _tkinter will queue an event for the interpreter thread, which will then
179 execute the command and pass back the result. If the main thread is not in the
180 mainloop, and invoking commands causes an exception; if the main loop is running
181 but not processing events, the command invocation will block.
182
183 In addition, for a threaded Tcl, a single global tcl_tstate won't be sufficient
184 anymore, since multiple Tcl interpreters may simultaneously dispatch in different
185 threads. So we use the Tcl TLS API.
186
Guido van Rossum00d93061998-05-28 23:06:38 +0000187*/
188
Guido van Rossum65d5b571998-12-21 19:32:43 +0000189static PyThread_type_lock tcl_lock = 0;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000190
191#ifdef TCL_THREADS
192static Tcl_ThreadDataKey state_key;
193typedef PyThreadState *ThreadSpecificData;
194#define tcl_tstate (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*)))
195#else
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000196static PyThreadState *tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000197#endif
Guido van Rossum00d93061998-05-28 23:06:38 +0000198
199#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000200 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000201 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000202
203#define LEAVE_TCL \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000204 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000205
Guido van Rossum62320c91998-06-15 04:36:09 +0000206#define ENTER_OVERLAP \
207 Py_END_ALLOW_THREADS
208
209#define LEAVE_OVERLAP_TCL \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000210 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000211
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000212#define ENTER_PYTHON \
213 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000214 if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000215
216#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000217 { PyThreadState *tstate = PyEval_SaveThread(); \
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000218 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
219
220#define CHECK_TCL_APPARTMENT \
221 if (((TkappObject *)self)->threaded && \
222 ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
223 PyErr_SetString(PyExc_RuntimeError, "Calling Tcl from different appartment"); \
224 return 0; \
225 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000226
227#else
228
229#define ENTER_TCL
230#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000231#define ENTER_OVERLAP
232#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000233#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000234#define LEAVE_PYTHON
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000235#define CHECK_TCL_APPARTMENT
Guido van Rossum00d93061998-05-28 23:06:38 +0000236
237#endif
238
Guido van Rossum97867b21996-08-08 19:09:53 +0000239#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000240#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000241#endif
242
Guido van Rossum18468821994-06-20 07:49:28 +0000243/**** Tkapp Object Declaration ****/
244
Jeremy Hylton938ace62002-07-17 16:30:39 +0000245static PyTypeObject Tkapp_Type;
Guido van Rossum18468821994-06-20 07:49:28 +0000246
Guido van Rossum00d93061998-05-28 23:06:38 +0000247typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000248 PyObject_HEAD
249 Tcl_Interp *interp;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000250 int wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000251 int threaded; /* True if tcl_platform[threaded] */
252 Tcl_ThreadId thread_id;
253 int dispatching;
254 /* We cannot include tclInt.h, as this is internal.
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000255 So we cache interesting types here. */
256 Tcl_ObjType *BooleanType;
257 Tcl_ObjType *ByteArrayType;
258 Tcl_ObjType *DoubleType;
259 Tcl_ObjType *IntType;
260 Tcl_ObjType *ListType;
261 Tcl_ObjType *ProcBodyType;
262 Tcl_ObjType *StringType;
Guido van Rossum00d93061998-05-28 23:06:38 +0000263} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000264
265#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000266#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000267#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000268
Guido van Rossum35d43371997-08-02 00:09:09 +0000269#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000270(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000271
Barry Warsawfa701a81997-01-16 00:15:11 +0000272
273
Guido van Rossum18468821994-06-20 07:49:28 +0000274/**** Error Handling ****/
275
276static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000277static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000278static int errorInCmd = 0;
279static PyObject *excInCmd;
280static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000282
Barry Warsawfa701a81997-01-16 00:15:11 +0000283
284
Guido van Rossum18468821994-06-20 07:49:28 +0000285static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000286Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000287{
Barry Warsawfa701a81997-01-16 00:15:11 +0000288 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
289 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000290}
291
Barry Warsawfa701a81997-01-16 00:15:11 +0000292
Barry Warsawfa701a81997-01-16 00:15:11 +0000293
Guido van Rossum18468821994-06-20 07:49:28 +0000294/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000295
Martin v. Löwis28e9ce92003-05-09 08:19:48 +0000296static int Tkinter_busywaitinterval = 20;
297
Guido van Rossum00d93061998-05-28 23:06:38 +0000298#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000299#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000300
Guido van Rossum00d93061998-05-28 23:06:38 +0000301/* Millisecond sleep() for Unix platforms. */
302
303static void
Fred Drake509d79a2000-07-08 04:04:38 +0000304Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000305{
306 /* XXX Too bad if you don't have select(). */
307 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000308 t.tv_sec = milli/1000;
309 t.tv_usec = (milli%1000) * 1000;
310 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
311}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000312#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000313
Martin v. Löwis5b26abb2002-12-28 09:23:09 +0000314/* Wait up to 1s for the mainloop to come up. */
315
316static int
317WaitForMainloop(TkappObject* self)
318{
319 int i;
320 for (i = 0; i < 10; i++) {
321 if (self->dispatching)
322 return 1;
323 Py_BEGIN_ALLOW_THREADS
324 Sleep(100);
325 Py_END_ALLOW_THREADS
326 }
327 if (self->dispatching)
328 return 1;
329 PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
330 return 0;
331}
Martin v. Löwisa9656492003-03-30 08:44:58 +0000332#endif /* WITH_THREAD */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000333
Guido van Rossum00d93061998-05-28 23:06:38 +0000334
Guido van Rossum18468821994-06-20 07:49:28 +0000335static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000336AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000337{
Guido van Rossum35d43371997-08-02 00:09:09 +0000338 if (PyString_Check(value))
339 return PyString_AsString(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000340 else if (PyUnicode_Check(value)) {
341 PyObject *v = PyUnicode_AsUTF8String(value);
342 if (v == NULL)
343 return NULL;
344 if (PyList_Append(tmp, v) != 0) {
345 Py_DECREF(v);
346 return NULL;
347 }
348 Py_DECREF(v);
349 return PyString_AsString(v);
350 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000351 else {
352 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000353 if (v == NULL)
354 return NULL;
355 if (PyList_Append(tmp, v) != 0) {
356 Py_DECREF(v);
357 return NULL;
358 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000359 Py_DECREF(v);
360 return PyString_AsString(v);
361 }
Guido van Rossum18468821994-06-20 07:49:28 +0000362}
363
Barry Warsawfa701a81997-01-16 00:15:11 +0000364
365
Guido van Rossum18468821994-06-20 07:49:28 +0000366#define ARGSZ 64
367
368static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000369Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000370{
Barry Warsawfa701a81997-01-16 00:15:11 +0000371 PyObject *tmp = NULL;
372 char *argvStore[ARGSZ];
373 char **argv = NULL;
374 int fvStore[ARGSZ];
375 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000376 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000377 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000378
Barry Warsawfa701a81997-01-16 00:15:11 +0000379 if (!(tmp = PyList_New(0)))
380 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000381
Barry Warsawfa701a81997-01-16 00:15:11 +0000382 argv = argvStore;
383 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000384
Barry Warsawfa701a81997-01-16 00:15:11 +0000385 if (args == NULL)
386 argc = 0;
387
388 else if (!PyTuple_Check(args)) {
389 argc = 1;
390 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000391 if (!(argv[0] = AsString(args, tmp)))
392 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000393 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000394 else {
395 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000396
Barry Warsawfa701a81997-01-16 00:15:11 +0000397 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000398 argv = (char **)ckalloc(argc * sizeof(char *));
399 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 if (argv == NULL || fv == NULL) {
401 PyErr_NoMemory();
402 goto finally;
403 }
404 }
405
406 for (i = 0; i < argc; i++) {
407 PyObject *v = PyTuple_GetItem(args, i);
408 if (PyTuple_Check(v)) {
409 fv[i] = 1;
410 if (!(argv[i] = Merge(v)))
411 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000412 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000413 }
414 else if (v == Py_None) {
415 argc = i;
416 break;
417 }
418 else {
419 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000420 if (!(argv[i] = AsString(v, tmp)))
421 goto finally;
422 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000423 }
424 }
Guido van Rossum18468821994-06-20 07:49:28 +0000425 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000426 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000427 if (res == NULL)
428 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000429
Barry Warsawfa701a81997-01-16 00:15:11 +0000430 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000431 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000432 if (fv[i]) {
433 ckfree(argv[i]);
434 }
435 if (argv != argvStore)
436 ckfree(FREECAST argv);
437 if (fv != fvStore)
438 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000439
Barry Warsawfa701a81997-01-16 00:15:11 +0000440 Py_DECREF(tmp);
441 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000442}
443
Barry Warsawfa701a81997-01-16 00:15:11 +0000444
445
Guido van Rossum18468821994-06-20 07:49:28 +0000446static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000447Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000448{
Barry Warsawfa701a81997-01-16 00:15:11 +0000449 int argc;
450 char **argv;
451 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000452
Barry Warsawfa701a81997-01-16 00:15:11 +0000453 if (list == NULL) {
454 Py_INCREF(Py_None);
455 return Py_None;
456 }
Guido van Rossum18468821994-06-20 07:49:28 +0000457
Guido van Rossum00d93061998-05-28 23:06:38 +0000458 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000459 /* Not a list.
460 * Could be a quoted string containing funnies, e.g. {"}.
461 * Return the string itself.
462 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000463 return PyString_FromString(list);
464 }
Guido van Rossum18468821994-06-20 07:49:28 +0000465
Barry Warsawfa701a81997-01-16 00:15:11 +0000466 if (argc == 0)
467 v = PyString_FromString("");
468 else if (argc == 1)
469 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000470 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 int i;
472 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000473
Barry Warsawfa701a81997-01-16 00:15:11 +0000474 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000475 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 Py_DECREF(v);
477 v = NULL;
478 break;
479 }
480 PyTuple_SetItem(v, i, w);
481 }
482 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000483 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000484 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000485}
486
Martin v. Löwisffad6332002-11-26 09:28:05 +0000487/* In some cases, Tcl will still return strings that are supposed to be
488 lists. SplitObj walks through a nested tuple, finding string objects that
489 need to be split. */
490
491PyObject *
492SplitObj(PyObject *arg)
493{
494 if (PyTuple_Check(arg)) {
495 int i, size;
496 PyObject *elem, *newelem, *result;
497
498 size = PyTuple_Size(arg);
499 result = NULL;
500 /* Recursively invoke SplitObj for all tuple items.
501 If this does not return a new object, no action is
502 needed. */
503 for(i = 0; i < size; i++) {
504 elem = PyTuple_GetItem(arg, i);
505 newelem = SplitObj(elem);
506 if (!newelem) {
507 Py_XDECREF(result);
508 return NULL;
509 }
510 if (!result) {
511 int k;
512 if (newelem == elem) {
513 Py_DECREF(newelem);
514 continue;
515 }
516 result = PyTuple_New(size);
517 if (!result)
518 return NULL;
519 for(k = 0; k < i; k++) {
520 elem = PyTuple_GetItem(arg, k);
521 Py_INCREF(elem);
522 PyTuple_SetItem(result, k, elem);
523 }
524 }
525 PyTuple_SetItem(result, i, newelem);
526 }
527 if (result)
528 return result;
529 /* Fall through, returning arg. */
530 }
531 else if (PyString_Check(arg)) {
532 int argc;
533 char **argv;
534 char *list = PyString_AsString(arg);
535
536 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
537 Py_INCREF(arg);
538 return arg;
539 }
540 Tcl_Free(FREECAST argv);
541 if (argc > 1)
542 return Split(PyString_AsString(arg));
543 /* Fall through, returning arg. */
544 }
545 Py_INCREF(arg);
546 return arg;
547}
Barry Warsawfa701a81997-01-16 00:15:11 +0000548
549
Guido van Rossum18468821994-06-20 07:49:28 +0000550/**** Tkapp Object ****/
551
552#ifndef WITH_APPINIT
553int
Fred Drake509d79a2000-07-08 04:04:38 +0000554Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000555{
Barry Warsawfa701a81997-01-16 00:15:11 +0000556 Tk_Window main;
David Aschere2b4b322004-02-18 05:59:53 +0000557 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000558
Barry Warsawfa701a81997-01-16 00:15:11 +0000559 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000560 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000561 return TCL_ERROR;
562 }
David Aschere2b4b322004-02-18 05:59:53 +0000563 _tkinter_skip_tk_init = Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
564 if (_tkinter_skip_tk_init == NULL || strcmp(_tkinter_skip_tk_init, "1") != 0) {
565 main = Tk_MainWindow(interp);
566 if (Tk_Init(interp) == TCL_ERROR) {
567 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
568 return TCL_ERROR;
569 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 }
571 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000572}
573#endif /* !WITH_APPINIT */
574
Guido van Rossum18468821994-06-20 07:49:28 +0000575
Barry Warsawfa701a81997-01-16 00:15:11 +0000576
577
578/* Initialize the Tk application; see the `main' function in
579 * `tkMain.c'.
580 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000581
Thomas Wouters58d05102000-07-24 14:43:35 +0000582static void EnableEventHook(void); /* Forward */
583static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000584
Barry Warsawfa701a81997-01-16 00:15:11 +0000585static TkappObject *
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000586Tkapp_New(char *screenName, char *baseName, char *className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000587 int interactive, int wantobjects, int wantTk, int sync, char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000588{
589 TkappObject *v;
590 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000591
Guido van Rossumb18618d2000-05-03 23:44:39 +0000592 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000593 if (v == NULL)
594 return NULL;
595
596 v->interp = Tcl_CreateInterp();
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000597 v->wantobjects = wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000598 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
599 TCL_GLOBAL_ONLY) != NULL;
600 v->thread_id = Tcl_GetCurrentThread();
601 v->dispatching = 0;
602
603#ifndef TCL_THREADS
604 if (v->threaded) {
605 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
606 Py_DECREF(v);
607 return 0;
608 }
609#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000610#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000611 if (v->threaded && tcl_lock) {
612 /* If Tcl is threaded, we don't need the lock. */
613 PyThread_free_lock(tcl_lock);
614 tcl_lock = NULL;
615 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000616#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000617
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000618 v->BooleanType = Tcl_GetObjType("boolean");
619 v->ByteArrayType = Tcl_GetObjType("bytearray");
620 v->DoubleType = Tcl_GetObjType("double");
621 v->IntType = Tcl_GetObjType("int");
622 v->ListType = Tcl_GetObjType("list");
623 v->ProcBodyType = Tcl_GetObjType("procbody");
624 v->StringType = Tcl_GetObjType("string");
625
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000626 /* Delete the 'exit' command, which can screw things up */
627 Tcl_DeleteCommand(v->interp, "exit");
628
Barry Warsawfa701a81997-01-16 00:15:11 +0000629 if (screenName != NULL)
630 Tcl_SetVar2(v->interp, "env", "DISPLAY",
631 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000632
Barry Warsawfa701a81997-01-16 00:15:11 +0000633 if (interactive)
634 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
635 else
636 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000637
Barry Warsawfa701a81997-01-16 00:15:11 +0000638 /* This is used to get the application class for Tk 4.1 and up */
639 argv0 = (char*)ckalloc(strlen(className) + 1);
640 if (!argv0) {
641 PyErr_NoMemory();
642 Py_DECREF(v);
643 return NULL;
644 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000645
Barry Warsawfa701a81997-01-16 00:15:11 +0000646 strcpy(argv0, className);
Neal Norwitz9dbc7dd2005-12-19 06:08:59 +0000647 if (isupper(Py_CHARMASK(argv0[0])))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000648 argv0[0] = tolower(Py_CHARMASK(argv0[0]));
Barry Warsawfa701a81997-01-16 00:15:11 +0000649 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
650 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000651
David Aschere2b4b322004-02-18 05:59:53 +0000652 if (! wantTk) {
653 Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
654 }
655
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000656 /* some initial arguments need to be in argv */
657 if (sync || use) {
Tim Peters51fa3b72004-08-04 02:16:48 +0000658 char *args;
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000659 int len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000660
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000661 if (sync)
662 len += sizeof "-sync";
663 if (use)
664 len += strlen(use) + sizeof "-use ";
665
Tim Peters51fa3b72004-08-04 02:16:48 +0000666 args = (char*)ckalloc(len);
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000667 if (!args) {
668 PyErr_NoMemory();
669 Py_DECREF(v);
670 return NULL;
671 }
672
673 args[0] = '\0';
674 if (sync)
675 strcat(args, "-sync");
676 if (use) {
677 if (sync)
678 strcat(args, " ");
679 strcat(args, "-use ");
680 strcat(args, use);
681 }
682
683 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
684 ckfree(args);
685 }
686
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000687 if (Tcl_AppInit(v->interp) != TCL_OK) {
688 PyObject *result = Tkinter_Error((PyObject *)v);
689 Py_DECREF((PyObject *)v);
690 return (TkappObject *)result;
691 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000692
Guido van Rossum7bf15641998-05-22 18:28:17 +0000693 EnableEventHook();
694
Barry Warsawfa701a81997-01-16 00:15:11 +0000695 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000696}
697
Barry Warsawfa701a81997-01-16 00:15:11 +0000698
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000699static void
700Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
701 Tcl_Condition *cond, Tcl_Mutex *mutex)
702{
703 Py_BEGIN_ALLOW_THREADS;
704 Tcl_MutexLock(mutex);
705 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
706 Tcl_ThreadAlert(self->thread_id);
707 Tcl_ConditionWait(cond, mutex, NULL);
708 Tcl_MutexUnlock(mutex);
709 Py_END_ALLOW_THREADS
710}
711
Barry Warsawfa701a81997-01-16 00:15:11 +0000712
Guido van Rossum18468821994-06-20 07:49:28 +0000713/** Tcl Eval **/
714
Martin v. Löwisffad6332002-11-26 09:28:05 +0000715typedef struct {
716 PyObject_HEAD
717 Tcl_Obj *value;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000718 PyObject *string; /* This cannot cause cycles. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000719} PyTclObject;
720
Neal Norwitz227b5332006-03-22 09:28:35 +0000721static PyTypeObject PyTclObject_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000722#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
723
724static PyObject *
725newPyTclObject(Tcl_Obj *arg)
726{
727 PyTclObject *self;
728 self = PyObject_New(PyTclObject, &PyTclObject_Type);
729 if (self == NULL)
730 return NULL;
731 Tcl_IncrRefCount(arg);
732 self->value = arg;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000733 self->string = NULL;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000734 return (PyObject*)self;
735}
736
737static void
738PyTclObject_dealloc(PyTclObject *self)
739{
740 Tcl_DecrRefCount(self->value);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000741 Py_XDECREF(self->string);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000742 PyObject_Del(self);
743}
744
745static PyObject *
746PyTclObject_str(PyTclObject *self)
747{
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000748 if (self->string && PyString_Check(self->string)) {
749 Py_INCREF(self->string);
750 return self->string;
751 }
752 /* XXX Could cache value if it is an ASCII string. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000753 return PyString_FromString(Tcl_GetString(self->value));
754}
755
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000756static char*
757PyTclObject_TclString(PyObject *self)
758{
759 return Tcl_GetString(((PyTclObject*)self)->value);
760}
761
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000762/* Like _str, but create Unicode if necessary. */
Martin v. Löwis39195712003-01-04 00:33:13 +0000763PyDoc_STRVAR(PyTclObject_string__doc__,
764"the string representation of this object, either as string or Unicode");
765
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000766static PyObject *
767PyTclObject_string(PyTclObject *self, void *ignored)
768{
769 char *s;
770 int i, len;
771 if (!self->string) {
772 s = Tcl_GetStringFromObj(self->value, &len);
773 for (i = 0; i < len; i++)
774 if (s[i] & 0x80)
775 break;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000776 if (i == len)
777 /* It is an ASCII string. */
778 self->string = PyString_FromStringAndSize(s, len);
779 else {
780 self->string = PyUnicode_DecodeUTF8(s, len, "strict");
781 if (!self->string) {
782 PyErr_Clear();
783 self->string = PyString_FromStringAndSize(s, len);
784 }
785 }
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000786 if (!self->string)
787 return NULL;
788 }
789 Py_INCREF(self->string);
790 return self->string;
791}
792
Martin v. Löwis39195712003-01-04 00:33:13 +0000793PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode");
794
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000795static PyObject *
796PyTclObject_unicode(PyTclObject *self, void *ignored)
797{
798 char *s;
799 int len;
800 if (self->string && PyUnicode_Check(self->string)) {
801 Py_INCREF(self->string);
802 return self->string;
803 }
804 /* XXX Could chache result if it is non-ASCII. */
805 s = Tcl_GetStringFromObj(self->value, &len);
806 return PyUnicode_DecodeUTF8(s, len, "strict");
807}
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000808
Martin v. Löwisffad6332002-11-26 09:28:05 +0000809static PyObject *
810PyTclObject_repr(PyTclObject *self)
811{
812 char buf[50];
Martin v. Löwisfba73692004-11-13 11:13:35 +0000813 PyOS_snprintf(buf, 50, "<%s object at %p>",
814 self->value->typePtr->name, self->value);
Walter Dörwald1ab83302007-05-18 17:15:44 +0000815 return PyUnicode_FromString(buf);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000816}
817
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000818static int
819PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
820{
821 int res;
822 res = strcmp(Tcl_GetString(self->value),
823 Tcl_GetString(other->value));
824 if (res < 0) return -1;
825 if (res > 0) return 1;
826 return 0;
827}
828
Martin v. Löwis39195712003-01-04 00:33:13 +0000829PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
830
Martin v. Löwisffad6332002-11-26 09:28:05 +0000831static PyObject*
832get_typename(PyTclObject* obj, void* ignored)
833{
834 return PyString_FromString(obj->value->typePtr->name);
835}
836
Martin v. Löwis39195712003-01-04 00:33:13 +0000837
Martin v. Löwisffad6332002-11-26 09:28:05 +0000838static PyGetSetDef PyTclObject_getsetlist[] = {
Martin v. Löwis39195712003-01-04 00:33:13 +0000839 {"typename", (getter)get_typename, NULL, get_typename__doc__},
840 {"string", (getter)PyTclObject_string, NULL,
841 PyTclObject_string__doc__},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000842 {0},
843};
844
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000845static PyMethodDef PyTclObject_methods[] = {
846 {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS,
Martin v. Löwis39195712003-01-04 00:33:13 +0000847 PyTclObject_unicode__doc__},
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000848 {0}
849};
850
Neal Norwitz227b5332006-03-22 09:28:35 +0000851static PyTypeObject PyTclObject_Type = {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000852 PyObject_HEAD_INIT(NULL)
853 0, /*ob_size*/
854 "_tkinter.Tcl_Obj", /*tp_name*/
855 sizeof(PyTclObject), /*tp_basicsize*/
856 0, /*tp_itemsize*/
857 /* methods */
858 (destructor)PyTclObject_dealloc, /*tp_dealloc*/
859 0, /*tp_print*/
860 0, /*tp_getattr*/
861 0, /*tp_setattr*/
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000862 (cmpfunc)PyTclObject_cmp, /*tp_compare*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000863 (reprfunc)PyTclObject_repr, /*tp_repr*/
864 0, /*tp_as_number*/
865 0, /*tp_as_sequence*/
866 0, /*tp_as_mapping*/
867 0, /*tp_hash*/
868 0, /*tp_call*/
869 (reprfunc)PyTclObject_str, /*tp_str*/
Jason Tishlerfb8595d2003-01-06 12:41:26 +0000870 PyObject_GenericGetAttr,/*tp_getattro*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000871 0, /*tp_setattro*/
872 0, /*tp_as_buffer*/
873 Py_TPFLAGS_DEFAULT, /*tp_flags*/
874 0, /*tp_doc*/
875 0, /*tp_traverse*/
876 0, /*tp_clear*/
877 0, /*tp_richcompare*/
878 0, /*tp_weaklistoffset*/
879 0, /*tp_iter*/
880 0, /*tp_iternext*/
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000881 PyTclObject_methods, /*tp_methods*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000882 0, /*tp_members*/
883 PyTclObject_getsetlist, /*tp_getset*/
884 0, /*tp_base*/
885 0, /*tp_dict*/
886 0, /*tp_descr_get*/
887 0, /*tp_descr_set*/
888 0, /*tp_dictoffset*/
889 0, /*tp_init*/
890 0, /*tp_alloc*/
891 0, /*tp_new*/
892 0, /*tp_free*/
893 0, /*tp_is_gc*/
894};
895
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000896static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000897AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000898{
899 Tcl_Obj *result;
900
901 if (PyString_Check(value))
902 return Tcl_NewStringObj(PyString_AS_STRING(value),
903 PyString_GET_SIZE(value));
Martin v. Löwis70c3dda2003-01-22 09:17:38 +0000904 else if (PyBool_Check(value))
905 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
Guido van Rossumddefaf32007-01-14 03:31:43 +0000906 else if (PyInt_CheckExact(value))
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000907 return Tcl_NewLongObj(PyInt_AS_LONG(value));
908 else if (PyFloat_Check(value))
909 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
910 else if (PyTuple_Check(value)) {
911 Tcl_Obj **argv = (Tcl_Obj**)
912 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
913 int i;
914 if(!argv)
915 return 0;
916 for(i=0;i<PyTuple_Size(value);i++)
917 argv[i] = AsObj(PyTuple_GetItem(value,i));
918 result = Tcl_NewListObj(PyTuple_Size(value), argv);
919 ckfree(FREECAST argv);
920 return result;
921 }
922 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000923 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000924 Py_ssize_t size = PyUnicode_GET_SIZE(value);
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000925 /* This #ifdef assumes that Tcl uses UCS-2.
926 See TCL_UTF_MAX test above. */
Martin v. Löwis6f29ff32003-04-16 20:34:55 +0000927#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000928 Tcl_UniChar *outbuf;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000929 Py_ssize_t i;
930 assert(size < size * sizeof(Tcl_UniChar));
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000931 outbuf = (Tcl_UniChar*)ckalloc(size * sizeof(Tcl_UniChar));
932 if (!outbuf) {
933 PyErr_NoMemory();
934 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000935 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000936 for (i = 0; i < size; i++) {
937 if (inbuf[i] >= 0x10000) {
938 /* Tcl doesn't do UTF-16, yet. */
939 PyErr_SetString(PyExc_ValueError,
940 "unsupported character");
941 ckfree(FREECAST outbuf);
942 return NULL;
943 }
944 outbuf[i] = inbuf[i];
945 }
946 result = Tcl_NewUnicodeObj(outbuf, size);
947 ckfree(FREECAST outbuf);
948 return result;
949#else
950 return Tcl_NewUnicodeObj(inbuf, size);
951#endif
952
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000953 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000954 else if(PyTclObject_Check(value)) {
955 Tcl_Obj *v = ((PyTclObject*)value)->value;
956 Tcl_IncrRefCount(v);
957 return v;
958 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000959 else {
960 PyObject *v = PyObject_Str(value);
961 if (!v)
962 return 0;
963 result = AsObj(v);
964 Py_DECREF(v);
965 return result;
966 }
967}
968
Martin v. Löwisffad6332002-11-26 09:28:05 +0000969static PyObject*
970FromObj(PyObject* tkapp, Tcl_Obj *value)
971{
972 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000973 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000974
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000975 if (value->typePtr == NULL) {
976 /* If the result contains any bytes with the top bit set,
977 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000978 int i;
979 char *s = value->bytes;
980 int len = value->length;
981 for (i = 0; i < len; i++) {
982 if (value->bytes[i] & 0x80)
983 break;
984 }
985
986 if (i == value->length)
987 result = PyString_FromStringAndSize(s, len);
988 else {
989 /* Convert UTF-8 to Unicode string */
990 result = PyUnicode_DecodeUTF8(s, len, "strict");
991 if (result == NULL) {
992 PyErr_Clear();
993 result = PyString_FromStringAndSize(s, len);
994 }
995 }
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000996 return result;
997 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000998
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000999 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001000 result = value->internalRep.longValue ? Py_True : Py_False;
1001 Py_INCREF(result);
1002 return result;
1003 }
1004
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001005 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001006 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +00001007 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001008 return PyString_FromStringAndSize(data, size);
1009 }
1010
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001011 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001012 return PyFloat_FromDouble(value->internalRep.doubleValue);
1013 }
1014
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001015 if (value->typePtr == app->IntType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001016 return PyInt_FromLong(value->internalRep.longValue);
1017 }
1018
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001019 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001020 int size;
1021 int i, status;
1022 PyObject *elem;
1023 Tcl_Obj *tcl_elem;
1024
1025 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
1026 if (status == TCL_ERROR)
1027 return Tkinter_Error(tkapp);
1028 result = PyTuple_New(size);
1029 if (!result)
1030 return NULL;
1031 for (i = 0; i < size; i++) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001032 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
Martin v. Löwisffad6332002-11-26 09:28:05 +00001033 value, i, &tcl_elem);
1034 if (status == TCL_ERROR) {
1035 Py_DECREF(result);
1036 return Tkinter_Error(tkapp);
1037 }
1038 elem = FromObj(tkapp, tcl_elem);
1039 if (!elem) {
1040 Py_DECREF(result);
1041 return NULL;
1042 }
1043 PyTuple_SetItem(result, i, elem);
1044 }
1045 return result;
1046 }
1047
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001048 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001049 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +00001050 }
1051
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001052 if (value->typePtr == app->StringType) {
Martin v. Löwis6f29ff32003-04-16 20:34:55 +00001053#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
Martin v. Löwisffad6332002-11-26 09:28:05 +00001054 PyObject *result;
1055 int size;
1056 Tcl_UniChar *input;
1057 Py_UNICODE *output;
1058
1059 size = Tcl_GetCharLength(value);
1060 result = PyUnicode_FromUnicode(NULL, size);
1061 if (!result)
1062 return NULL;
1063 input = Tcl_GetUnicode(value);
1064 output = PyUnicode_AS_UNICODE(result);
1065 while (size--)
1066 *output++ = *input++;
1067 return result;
1068#else
1069 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1070 Tcl_GetCharLength(value));
1071#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +00001072 }
1073
1074 return newPyTclObject(value);
1075}
1076
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001077/* This mutex synchronizes inter-thread command calls. */
1078
1079TCL_DECLARE_MUTEX(call_mutex)
1080
1081typedef struct Tkapp_CallEvent {
1082 Tcl_Event ev; /* Must be first */
1083 TkappObject *self;
1084 PyObject *args;
1085 int flags;
1086 PyObject **res;
1087 PyObject **exc_type, **exc_value, **exc_tb;
1088 Tcl_Condition done;
1089} Tkapp_CallEvent;
1090
1091void
1092Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001093{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001094 int i;
1095 for (i = 0; i < objc; i++)
1096 Tcl_DecrRefCount(objv[i]);
1097 if (objv != objStore)
1098 ckfree(FREECAST objv);
1099}
Guido van Rossum18468821994-06-20 07:49:28 +00001100
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001101/* Convert Python objects to Tcl objects. This must happen in the
1102 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001103
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001104static Tcl_Obj**
1105Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1106{
1107 Tcl_Obj **objv = objStore;
Martin v. Löwis7d134952002-12-12 19:05:48 +00001108 int objc = 0, i;
Guido van Rossum212643f1998-04-29 16:22:14 +00001109 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +00001110 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001111
Guido van Rossum212643f1998-04-29 16:22:14 +00001112 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +00001113 objv[0] = AsObj(args);
1114 if (objv[0] == 0)
1115 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001116 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +00001117 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001118 }
1119 else {
Guido van Rossum632de272000-03-29 00:19:50 +00001120 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001121
Guido van Rossum632de272000-03-29 00:19:50 +00001122 if (objc > ARGSZ) {
1123 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1124 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001125 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +00001126 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +00001127 goto finally;
1128 }
1129 }
1130
Guido van Rossum632de272000-03-29 00:19:50 +00001131 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001132 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +00001133 if (v == Py_None) {
1134 objc = i;
1135 break;
1136 }
Guido van Rossum632de272000-03-29 00:19:50 +00001137 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +00001138 if (!objv[i]) {
1139 /* Reset objc, so it attempts to clear
1140 objects only up to i. */
1141 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +00001142 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001143 }
Guido van Rossum632de272000-03-29 00:19:50 +00001144 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001145 }
1146 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001147 *pobjc = objc;
1148 return objv;
1149finally:
1150 Tkapp_CallDeallocArgs(objv, objStore, objc);
1151 return NULL;
1152}
Guido van Rossum212643f1998-04-29 16:22:14 +00001153
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001154/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001155
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001156static PyObject*
1157Tkapp_CallResult(TkappObject *self)
1158{
1159 PyObject *res = NULL;
1160 if(self->wantobjects) {
1161 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001162 /* Not sure whether the IncrRef is necessary, but something
1163 may overwrite the interpreter result while we are
1164 converting it. */
1165 Tcl_IncrRefCount(value);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001166 res = FromObj((PyObject*)self, value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001167 Tcl_DecrRefCount(value);
1168 } else {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001169 const char *s = Tcl_GetStringResult(self->interp);
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001170 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001171
Guido van Rossum990f5c62000-05-04 15:07:16 +00001172 /* If the result contains any bytes with the top bit set,
1173 it's UTF-8 and we should decode it to Unicode */
1174 while (*p != '\0') {
1175 if (*p & 0x80)
1176 break;
1177 p++;
1178 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001179
Guido van Rossum990f5c62000-05-04 15:07:16 +00001180 if (*p == '\0')
1181 res = PyString_FromStringAndSize(s, (int)(p-s));
1182 else {
1183 /* Convert UTF-8 to Unicode string */
1184 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +00001185 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
1186 if (res == NULL) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001187 PyErr_Clear();
1188 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +00001189 }
Guido van Rossum990f5c62000-05-04 15:07:16 +00001190 }
1191 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001192 return res;
1193}
Guido van Rossum632de272000-03-29 00:19:50 +00001194
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001195/* Tkapp_CallProc is the event procedure that is executed in the context of
1196 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1197 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001198
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001199static int
1200Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1201{
1202 Tcl_Obj *objStore[ARGSZ];
1203 Tcl_Obj **objv;
1204 int objc;
1205 int i;
1206 ENTER_PYTHON
1207 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1208 if (!objv) {
1209 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1210 *(e->res) = NULL;
1211 }
1212 LEAVE_PYTHON
1213 if (!objv)
1214 goto done;
1215 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1216 ENTER_PYTHON
1217 if (i == TCL_ERROR) {
1218 *(e->res) = NULL;
1219 *(e->exc_type) = NULL;
1220 *(e->exc_tb) = NULL;
1221 *(e->exc_value) = PyObject_CallFunction(
1222 Tkinter_TclError, "s",
1223 Tcl_GetStringResult(e->self->interp));
1224 }
1225 else {
1226 *(e->res) = Tkapp_CallResult(e->self);
1227 }
1228 LEAVE_PYTHON
1229 done:
1230 /* Wake up calling thread. */
1231 Tcl_MutexLock(&call_mutex);
1232 Tcl_ConditionNotify(&e->done);
1233 Tcl_MutexUnlock(&call_mutex);
1234 return 1;
1235}
1236
1237/* This is the main entry point for calling a Tcl command.
1238 It supports three cases, with regard to threading:
1239 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1240 the context of the calling thread.
1241 2. Tcl is threaded, caller of the command is in the interpreter thread:
1242 Execute the command in the calling thread. Since the Tcl lock will
1243 not be used, we can merge that with case 1.
1244 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1245 the interpreter thread. Allocation of Tcl objects needs to occur in the
1246 interpreter thread, so we ship the PyObject* args to the target thread,
1247 and perform processing there. */
1248
1249static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001250Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001251{
1252 Tcl_Obj *objStore[ARGSZ];
1253 Tcl_Obj **objv = NULL;
1254 int objc, i;
1255 PyObject *res = NULL;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001256 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001257 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
1258 int flags = TCL_EVAL_DIRECT;
1259
Martin v. Löwisa9656492003-03-30 08:44:58 +00001260#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001261 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1262 /* We cannot call the command directly. Instead, we must
1263 marshal the parameters to the interpreter thread. */
1264 Tkapp_CallEvent *ev;
1265 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001266 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001267 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001268 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1269 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1270 ev->self = self;
1271 ev->args = args;
1272 ev->res = &res;
1273 ev->exc_type = &exc_type;
1274 ev->exc_value = &exc_value;
1275 ev->exc_tb = &exc_tb;
1276 ev->done = (Tcl_Condition)0;
1277
1278 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &call_mutex);
1279
1280 if (res == NULL) {
1281 if (exc_type)
1282 PyErr_Restore(exc_type, exc_value, exc_tb);
1283 else
1284 PyErr_SetObject(Tkinter_TclError, exc_value);
1285 }
1286 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001287 else
1288#endif
1289 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001290
1291 objv = Tkapp_CallArgs(args, objStore, &objc);
1292 if (!objv)
1293 return NULL;
1294
1295 ENTER_TCL
1296
1297 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1298
1299 ENTER_OVERLAP
1300
1301 if (i == TCL_ERROR)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001302 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001303 else
1304 res = Tkapp_CallResult(self);
1305
1306 LEAVE_OVERLAP_TCL
1307
1308 Tkapp_CallDeallocArgs(objv, objStore, objc);
1309 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001310 return res;
1311}
1312
1313
1314static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001315Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001316{
Guido van Rossum212643f1998-04-29 16:22:14 +00001317 /* Could do the same here as for Tkapp_Call(), but this is not used
1318 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1319 way for the user to do what all its Global* variants do (save and
1320 reset the scope pointer, call the local version, restore the saved
1321 scope pointer). */
1322
Guido van Rossum62320c91998-06-15 04:36:09 +00001323 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001324 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001325
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001326 CHECK_TCL_APPARTMENT;
1327
Guido van Rossum62320c91998-06-15 04:36:09 +00001328 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001329 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001330 int err;
1331 ENTER_TCL
1332 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001333 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001334 if (err == TCL_ERROR)
1335 res = Tkinter_Error(self);
1336 else
1337 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001338 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001339 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001340 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001341
1342 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001343}
1344
1345static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001346Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001347{
Barry Warsawfa701a81997-01-16 00:15:11 +00001348 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001349 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001350 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001351
Guido van Rossum43713e52000-02-29 13:59:29 +00001352 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001353 return NULL;
1354
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001355 CHECK_TCL_APPARTMENT;
1356
Guido van Rossum00d93061998-05-28 23:06:38 +00001357 ENTER_TCL
1358 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001359 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001360 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001361 res = Tkinter_Error(self);
1362 else
1363 res = PyString_FromString(Tkapp_Result(self));
1364 LEAVE_OVERLAP_TCL
1365 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001366}
1367
1368static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001369Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001370{
Barry Warsawfa701a81997-01-16 00:15:11 +00001371 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001372 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001373 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001374
Guido van Rossum43713e52000-02-29 13:59:29 +00001375 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001376 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001377
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001378 CHECK_TCL_APPARTMENT;
1379
Guido van Rossum00d93061998-05-28 23:06:38 +00001380 ENTER_TCL
1381 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001382 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001383 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001384 res = Tkinter_Error(self);
1385 else
1386 res = PyString_FromString(Tkapp_Result(self));
1387 LEAVE_OVERLAP_TCL
1388 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001389}
1390
1391static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001392Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001393{
Barry Warsawfa701a81997-01-16 00:15:11 +00001394 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001395 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001396 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001397
Guido van Rossum43713e52000-02-29 13:59:29 +00001398 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001399 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001400
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001401 CHECK_TCL_APPARTMENT;
1402
Guido van Rossum00d93061998-05-28 23:06:38 +00001403 ENTER_TCL
1404 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001405 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001406 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001407 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001408
Guido van Rossum62320c91998-06-15 04:36:09 +00001409 else
1410 res = PyString_FromString(Tkapp_Result(self));
1411 LEAVE_OVERLAP_TCL
1412 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001413}
1414
1415static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001416Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001417{
Barry Warsawfa701a81997-01-16 00:15:11 +00001418 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001419 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001420 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001421
Guido van Rossum35d43371997-08-02 00:09:09 +00001422 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001423 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001424
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001425 CHECK_TCL_APPARTMENT;
1426
Guido van Rossum00d93061998-05-28 23:06:38 +00001427 ENTER_TCL
1428 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001429 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001430 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001431 res = Tkinter_Error(self);
1432 else
1433 res = PyString_FromString(Tkapp_Result(self));
1434 LEAVE_OVERLAP_TCL
1435 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001436}
1437
1438static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001439Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001440{
Barry Warsawfa701a81997-01-16 00:15:11 +00001441 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001442
Guido van Rossum43713e52000-02-29 13:59:29 +00001443 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001444 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001445 CHECK_TCL_APPARTMENT;
1446
Guido van Rossum00d93061998-05-28 23:06:38 +00001447 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001448 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001449 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001450
Barry Warsawfa701a81997-01-16 00:15:11 +00001451 Py_INCREF(Py_None);
1452 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001453}
1454
Barry Warsawfa701a81997-01-16 00:15:11 +00001455
1456
Guido van Rossum18468821994-06-20 07:49:28 +00001457/** Tcl Variable **/
1458
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001459TCL_DECLARE_MUTEX(var_mutex)
1460
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001461typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001462typedef struct VarEvent {
1463 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001464 PyObject *self;
1465 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001466 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001467 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001468 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001469 PyObject **exc_type;
1470 PyObject **exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001471 Tcl_Condition cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001472} VarEvent;
1473
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001474static int
1475varname_converter(PyObject *in, void *_out)
1476{
1477 char **out = (char**)_out;
1478 if (PyString_Check(in)) {
1479 *out = PyString_AsString(in);
1480 return 1;
1481 }
1482 if (PyTclObject_Check(in)) {
1483 *out = PyTclObject_TclString(in);
1484 return 1;
1485 }
1486 /* XXX: Should give diagnostics. */
1487 return 0;
1488}
1489
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001490void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001491var_perform(VarEvent *ev)
1492{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001493 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1494 if (!*(ev->res)) {
1495 PyObject *exc, *val, *tb;
1496 PyErr_Fetch(&exc, &val, &tb);
1497 PyErr_NormalizeException(&exc, &val, &tb);
1498 *(ev->exc_type) = exc;
1499 *(ev->exc_val) = val;
1500 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001501 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001502
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001503}
1504
1505static int
1506var_proc(VarEvent* ev, int flags)
1507{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001508 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001509 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001510 Tcl_MutexLock(&var_mutex);
1511 Tcl_ConditionNotify(&ev->cond);
1512 Tcl_MutexUnlock(&var_mutex);
1513 LEAVE_PYTHON
1514 return 1;
1515}
1516
1517static PyObject*
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001518var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001519{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001520 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisa9656492003-03-30 08:44:58 +00001521#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001522 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001523 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001524 VarEvent *ev;
1525 PyObject *res, *exc_type, *exc_val;
1526
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001527 /* The current thread is not the interpreter thread. Marshal
1528 the call to the interpreter thread, then wait for
1529 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001530 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001531 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001532
1533 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1534
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001535 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001536 ev->args = args;
1537 ev->flags = flags;
1538 ev->func = func;
1539 ev->res = &res;
1540 ev->exc_type = &exc_type;
1541 ev->exc_val = &exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001542 ev->cond = NULL;
1543 ev->ev.proc = (Tcl_EventProc*)var_proc;
1544 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001545 if (!res) {
1546 PyErr_SetObject(exc_type, exc_val);
1547 Py_DECREF(exc_type);
1548 Py_DECREF(exc_val);
1549 return NULL;
1550 }
1551 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001552 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001553#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001554 /* Tcl is not threaded, or this is the interpreter thread. */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001555 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001556}
1557
Guido van Rossum18468821994-06-20 07:49:28 +00001558static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001559SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001560{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001561 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001562 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001563 PyObject *res = NULL;
1564 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001565
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001566 if (PyArg_ParseTuple(args, "O&O:setvar",
1567 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001568 /* XXX Acquire tcl lock??? */
1569 newval = AsObj(newValue);
1570 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001571 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001572 ENTER_TCL
1573 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1574 newval, flags);
1575 ENTER_OVERLAP
1576 if (!ok)
1577 Tkinter_Error(self);
1578 else {
1579 res = Py_None;
1580 Py_INCREF(res);
1581 }
1582 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001583 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001584 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001585 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001586 if (PyArg_ParseTuple(args, "ssO:setvar",
1587 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001588 /* XXX must hold tcl lock already??? */
1589 newval = AsObj(newValue);
1590 ENTER_TCL
1591 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1592 ENTER_OVERLAP
1593 if (!ok)
1594 Tkinter_Error(self);
1595 else {
1596 res = Py_None;
1597 Py_INCREF(res);
1598 }
1599 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001600 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001601 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001602 return NULL;
1603 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001604 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001605 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001606}
1607
1608static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001609Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001610{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001611 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001612}
1613
1614static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001615Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001616{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001617 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001618}
1619
Barry Warsawfa701a81997-01-16 00:15:11 +00001620
1621
Guido van Rossum18468821994-06-20 07:49:28 +00001622static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001623GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001624{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001625 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001626 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001627 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001628
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001629 if (!PyArg_ParseTuple(args, "O&|s:getvar",
1630 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001631 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001632
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001633 ENTER_TCL
1634 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1635 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001636 if (tres == NULL) {
1637 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1638 } else {
1639 if (((TkappObject*)self)->wantobjects) {
1640 res = FromObj(self, tres);
1641 }
1642 else {
1643 res = PyString_FromString(Tcl_GetString(tres));
1644 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001645 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001646 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001647 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001648}
1649
1650static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001651Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001652{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001653 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001654}
1655
1656static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001657Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001658{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001659 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001660}
1661
Barry Warsawfa701a81997-01-16 00:15:11 +00001662
1663
Guido van Rossum18468821994-06-20 07:49:28 +00001664static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001665UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001666{
Guido van Rossum35d43371997-08-02 00:09:09 +00001667 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001668 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001669 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001670
Guido van Rossum43713e52000-02-29 13:59:29 +00001671 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001672 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001673
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001674 ENTER_TCL
1675 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1676 ENTER_OVERLAP
1677 if (code == TCL_ERROR)
1678 res = Tkinter_Error(self);
1679 else {
1680 Py_INCREF(Py_None);
1681 res = Py_None;
1682 }
1683 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001684 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001685}
1686
1687static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001688Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001689{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001690 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001691}
1692
1693static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001694Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001695{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001696 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001697}
1698
Barry Warsawfa701a81997-01-16 00:15:11 +00001699
1700
Guido van Rossum18468821994-06-20 07:49:28 +00001701/** Tcl to Python **/
1702
1703static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001704Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001705{
Barry Warsawfa701a81997-01-16 00:15:11 +00001706 char *s;
1707 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001708
Martin v. Löwisffad6332002-11-26 09:28:05 +00001709 if (PyTuple_Size(args) == 1) {
1710 PyObject* o = PyTuple_GetItem(args, 0);
1711 if (PyInt_Check(o)) {
1712 Py_INCREF(o);
1713 return o;
1714 }
1715 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001716 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001717 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001718 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001719 return Tkinter_Error(self);
1720 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001721}
1722
1723static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001724Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001725{
Barry Warsawfa701a81997-01-16 00:15:11 +00001726 char *s;
1727 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001728
Martin v. Löwisffad6332002-11-26 09:28:05 +00001729 if (PyTuple_Size(args) == 1) {
1730 PyObject *o = PyTuple_GetItem(args, 0);
1731 if (PyFloat_Check(o)) {
1732 Py_INCREF(o);
1733 return o;
1734 }
1735 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001736 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001737 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001738 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001739 return Tkinter_Error(self);
1740 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001741}
1742
1743static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001744Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001745{
Barry Warsawfa701a81997-01-16 00:15:11 +00001746 char *s;
1747 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001748
Martin v. Löwisffad6332002-11-26 09:28:05 +00001749 if (PyTuple_Size(args) == 1) {
1750 PyObject *o = PyTuple_GetItem(args, 0);
1751 if (PyInt_Check(o)) {
1752 Py_INCREF(o);
1753 return o;
1754 }
1755 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001756 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001757 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001758 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1759 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001760 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001761}
1762
1763static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001764Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001765{
Barry Warsawfa701a81997-01-16 00:15:11 +00001766 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001767 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001768 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001769
Guido van Rossum43713e52000-02-29 13:59:29 +00001770 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001771 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001772
1773 CHECK_TCL_APPARTMENT;
1774
Guido van Rossum00d93061998-05-28 23:06:38 +00001775 ENTER_TCL
1776 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001777 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001778 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001779 res = Tkinter_Error(self);
1780 else
1781 res = Py_BuildValue("s", Tkapp_Result(self));
1782 LEAVE_OVERLAP_TCL
1783 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001784}
1785
1786static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001787Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001788{
Barry Warsawfa701a81997-01-16 00:15:11 +00001789 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001790 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001791 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001792 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001793
Guido van Rossum43713e52000-02-29 13:59:29 +00001794 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001795 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001796
1797 CHECK_TCL_APPARTMENT;
1798
Guido van Rossum00d93061998-05-28 23:06:38 +00001799 ENTER_TCL
1800 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001801 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001802 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001803 res = Tkinter_Error(self);
1804 else
1805 res = Py_BuildValue("l", v);
1806 LEAVE_OVERLAP_TCL
1807 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001808}
1809
1810static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001811Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001812{
Barry Warsawfa701a81997-01-16 00:15:11 +00001813 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001814 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001815 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001816 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001817
Guido van Rossum43713e52000-02-29 13:59:29 +00001818 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001819 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001820 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001821 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001822 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001823 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001824 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001825 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001826 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001827 res = Tkinter_Error(self);
1828 else
1829 res = Py_BuildValue("d", v);
1830 LEAVE_OVERLAP_TCL
1831 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001832}
1833
1834static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001835Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001836{
Barry Warsawfa701a81997-01-16 00:15:11 +00001837 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001838 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001839 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001840 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001841
Guido van Rossum43713e52000-02-29 13:59:29 +00001842 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001843 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001844 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001845 ENTER_TCL
1846 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001847 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001848 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001849 res = Tkinter_Error(self);
1850 else
1851 res = Py_BuildValue("i", v);
1852 LEAVE_OVERLAP_TCL
1853 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001854}
1855
Barry Warsawfa701a81997-01-16 00:15:11 +00001856
1857
Guido van Rossum18468821994-06-20 07:49:28 +00001858static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001859Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001860{
Barry Warsawfa701a81997-01-16 00:15:11 +00001861 char *list;
1862 int argc;
1863 char **argv;
1864 PyObject *v;
1865 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001866
Martin v. Löwisffad6332002-11-26 09:28:05 +00001867 if (PyTuple_Size(args) == 1) {
1868 v = PyTuple_GetItem(args, 0);
1869 if (PyTuple_Check(v)) {
1870 Py_INCREF(v);
1871 return v;
1872 }
1873 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001874 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001875 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001876
Neal Norwitzd1c55102003-05-29 00:17:03 +00001877 if (Tcl_SplitList(Tkapp_Interp(self), list,
1878 &argc, &argv) == TCL_ERROR) {
1879 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001880 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001881 }
Guido van Rossum18468821994-06-20 07:49:28 +00001882
Barry Warsawfa701a81997-01-16 00:15:11 +00001883 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001884 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001885
Barry Warsawfa701a81997-01-16 00:15:11 +00001886 for (i = 0; i < argc; i++) {
1887 PyObject *s = PyString_FromString(argv[i]);
1888 if (!s || PyTuple_SetItem(v, i, s)) {
1889 Py_DECREF(v);
1890 v = NULL;
1891 goto finally;
1892 }
1893 }
Guido van Rossum18468821994-06-20 07:49:28 +00001894
Barry Warsawfa701a81997-01-16 00:15:11 +00001895 finally:
1896 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001897 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001898 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001899}
1900
1901static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001902Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001903{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001904 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001905 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001906
Martin v. Löwisffad6332002-11-26 09:28:05 +00001907 if (PyTuple_Size(args) == 1) {
1908 PyObject* o = PyTuple_GetItem(args, 0);
1909 if (PyTuple_Check(o)) {
1910 o = SplitObj(o);
1911 return o;
1912 }
1913 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001914 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001915 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00001916 v = Split(list);
1917 PyMem_Free(list);
1918 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001919}
1920
1921static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001922Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001923{
Barry Warsawfa701a81997-01-16 00:15:11 +00001924 char *s = Merge(args);
1925 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001926
Barry Warsawfa701a81997-01-16 00:15:11 +00001927 if (s) {
1928 res = PyString_FromString(s);
1929 ckfree(s);
1930 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001931
1932 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001933}
1934
Barry Warsawfa701a81997-01-16 00:15:11 +00001935
1936
Guido van Rossum18468821994-06-20 07:49:28 +00001937/** Tcl Command **/
1938
Guido van Rossum00d93061998-05-28 23:06:38 +00001939/* Client data struct */
1940typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001941 PyObject *self;
1942 PyObject *func;
1943} PythonCmd_ClientData;
1944
1945static int
Fred Drake509d79a2000-07-08 04:04:38 +00001946PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001947{
1948 errorInCmd = 1;
1949 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1950 LEAVE_PYTHON
1951 return TCL_ERROR;
1952}
1953
Guido van Rossum18468821994-06-20 07:49:28 +00001954/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001955 * function or method.
1956 */
Guido van Rossum18468821994-06-20 07:49:28 +00001957static int
Fred Drake509d79a2000-07-08 04:04:38 +00001958PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001959{
Guido van Rossum00d93061998-05-28 23:06:38 +00001960 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001961 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001962 int i, rv;
1963 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001964
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001965 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001966
Barry Warsawfa701a81997-01-16 00:15:11 +00001967 /* TBD: no error checking here since we know, via the
1968 * Tkapp_CreateCommand() that the client data is a two-tuple
1969 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001970 self = data->self;
1971 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001972
Barry Warsawfa701a81997-01-16 00:15:11 +00001973 /* Create argument list (argv1, ..., argvN) */
1974 if (!(arg = PyTuple_New(argc - 1)))
1975 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001976
Barry Warsawfa701a81997-01-16 00:15:11 +00001977 for (i = 0; i < (argc - 1); i++) {
1978 PyObject *s = PyString_FromString(argv[i + 1]);
1979 if (!s || PyTuple_SetItem(arg, i, s)) {
1980 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001981 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001982 }
1983 }
1984 res = PyEval_CallObject(func, arg);
1985 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001986
Barry Warsawfa701a81997-01-16 00:15:11 +00001987 if (res == NULL)
1988 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001989
Barry Warsawfa701a81997-01-16 00:15:11 +00001990 if (!(tmp = PyList_New(0))) {
1991 Py_DECREF(res);
1992 return PythonCmd_Error(interp);
1993 }
1994
Guido van Rossum2834b972000-10-06 16:58:26 +00001995 s = AsString(res, tmp);
1996 if (s == NULL) {
1997 rv = PythonCmd_Error(interp);
1998 }
1999 else {
2000 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
2001 rv = TCL_OK;
2002 }
2003
Barry Warsawfa701a81997-01-16 00:15:11 +00002004 Py_DECREF(res);
2005 Py_DECREF(tmp);
2006
Guido van Rossum00d93061998-05-28 23:06:38 +00002007 LEAVE_PYTHON
2008
Guido van Rossum2834b972000-10-06 16:58:26 +00002009 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002010}
2011
2012static void
Fred Drake509d79a2000-07-08 04:04:38 +00002013PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002014{
Guido van Rossum00d93061998-05-28 23:06:38 +00002015 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2016
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002017 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002018 Py_XDECREF(data->self);
2019 Py_XDECREF(data->func);
2020 PyMem_DEL(data);
2021 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002022}
2023
Barry Warsawfa701a81997-01-16 00:15:11 +00002024
2025
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002026
2027TCL_DECLARE_MUTEX(command_mutex)
2028
2029typedef struct CommandEvent{
2030 Tcl_Event ev;
2031 Tcl_Interp* interp;
2032 char *name;
2033 int create;
2034 int *status;
2035 ClientData *data;
2036 Tcl_Condition done;
2037} CommandEvent;
2038
2039static int
2040Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002041{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002042 if (ev->create)
2043 *ev->status = Tcl_CreateCommand(
2044 ev->interp, ev->name, PythonCmd,
2045 ev->data, PythonCmdDelete) == NULL;
2046 else
2047 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2048 Tcl_MutexLock(&command_mutex);
2049 Tcl_ConditionNotify(&ev->done);
2050 Tcl_MutexUnlock(&command_mutex);
2051 return 1;
2052}
2053
2054static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002055Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002056{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002057 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002058 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002059 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002060 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002061 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002062
Guido van Rossum43713e52000-02-29 13:59:29 +00002063 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002064 return NULL;
2065 if (!PyCallable_Check(func)) {
2066 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002067 return NULL;
2068 }
Guido van Rossum18468821994-06-20 07:49:28 +00002069
Martin v. Löwisa9656492003-03-30 08:44:58 +00002070#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002071 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002072 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002073 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002074#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002075
Guido van Rossum00d93061998-05-28 23:06:38 +00002076 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002077 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002078 return PyErr_NoMemory();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002079 Py_INCREF(self);
2080 Py_INCREF(func);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002081 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002082 data->func = func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002083
2084 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2085 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2086 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2087 ev->interp = self->interp;
2088 ev->create = 1;
2089 ev->name = cmdName;
2090 ev->data = (ClientData)data;
2091 ev->status = &err;
2092 ev->done = NULL;
2093 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
2094 }
2095 else {
2096 ENTER_TCL
2097 err = Tcl_CreateCommand(
2098 Tkapp_Interp(self), cmdName, PythonCmd,
2099 (ClientData)data, PythonCmdDelete) == NULL;
2100 LEAVE_TCL
2101 }
2102 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002103 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002104 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002105 return NULL;
2106 }
Guido van Rossum18468821994-06-20 07:49:28 +00002107
Barry Warsawfa701a81997-01-16 00:15:11 +00002108 Py_INCREF(Py_None);
2109 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002110}
2111
Barry Warsawfa701a81997-01-16 00:15:11 +00002112
2113
Guido van Rossum18468821994-06-20 07:49:28 +00002114static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002115Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002116{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002117 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002118 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002119 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002120
Guido van Rossum43713e52000-02-29 13:59:29 +00002121 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002122 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002123 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2124 CommandEvent *ev;
2125 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2126 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2127 ev->interp = self->interp;
2128 ev->create = 0;
2129 ev->name = cmdName;
2130 ev->status = &err;
2131 ev->done = NULL;
2132 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done,
2133 &command_mutex);
2134 }
2135 else {
2136 ENTER_TCL
2137 err = Tcl_DeleteCommand(self->interp, cmdName);
2138 LEAVE_TCL
2139 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002140 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002141 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2142 return NULL;
2143 }
2144 Py_INCREF(Py_None);
2145 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002146}
2147
Barry Warsawfa701a81997-01-16 00:15:11 +00002148
2149
Guido van Rossum00d93061998-05-28 23:06:38 +00002150#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002151/** File Handler **/
2152
Guido van Rossum00d93061998-05-28 23:06:38 +00002153typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002154 PyObject *func;
2155 PyObject *file;
2156 int id;
2157 struct _fhcdata *next;
2158} FileHandler_ClientData;
2159
2160static FileHandler_ClientData *HeadFHCD;
2161
2162static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002163NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002164{
2165 FileHandler_ClientData *p;
2166 p = PyMem_NEW(FileHandler_ClientData, 1);
2167 if (p != NULL) {
2168 Py_XINCREF(func);
2169 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002170 p->func = func;
2171 p->file = file;
2172 p->id = id;
2173 p->next = HeadFHCD;
2174 HeadFHCD = p;
2175 }
2176 return p;
2177}
2178
2179static void
Fred Drake509d79a2000-07-08 04:04:38 +00002180DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002181{
2182 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002183
2184 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002185 while ((p = *pp) != NULL) {
2186 if (p->id == id) {
2187 *pp = p->next;
2188 Py_XDECREF(p->func);
2189 Py_XDECREF(p->file);
2190 PyMem_DEL(p);
2191 }
2192 else
2193 pp = &p->next;
2194 }
2195}
2196
Guido van Rossuma597dde1995-01-10 20:56:29 +00002197static void
Fred Drake509d79a2000-07-08 04:04:38 +00002198FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002199{
Guido van Rossum00d93061998-05-28 23:06:38 +00002200 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002201 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002202
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002203 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002204 func = data->func;
2205 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002206
Barry Warsawfa701a81997-01-16 00:15:11 +00002207 arg = Py_BuildValue("(Oi)", file, (long) mask);
2208 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002209 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002210
2211 if (res == NULL) {
2212 errorInCmd = 1;
2213 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2214 }
2215 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002216 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002217}
2218
Guido van Rossum18468821994-06-20 07:49:28 +00002219static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002220Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2221 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002222{
Guido van Rossum00d93061998-05-28 23:06:38 +00002223 FileHandler_ClientData *data;
2224 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002225 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002226
Guido van Rossum2834b972000-10-06 16:58:26 +00002227 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2228 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002229 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002230
Martin v. Löwisa9656492003-03-30 08:44:58 +00002231#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002232 if (!self && !tcl_lock) {
2233 /* We don't have the Tcl lock since Tcl is threaded. */
2234 PyErr_SetString(PyExc_RuntimeError,
2235 "_tkinter.createfilehandler not supported "
2236 "for threaded Tcl");
2237 return NULL;
2238 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002239#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002240
2241 if (self) {
2242 CHECK_TCL_APPARTMENT;
2243 }
2244
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002245 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002246 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002247 return NULL;
2248 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002249 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002250 return NULL;
2251 }
2252
Guido van Rossuma80649b2000-03-28 20:07:05 +00002253 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002254 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002255 return NULL;
2256
Barry Warsawfa701a81997-01-16 00:15:11 +00002257 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002258 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002259 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002260 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002261 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002262 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002263}
2264
2265static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002266Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002267{
Barry Warsawfa701a81997-01-16 00:15:11 +00002268 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002269 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002270
Guido van Rossum43713e52000-02-29 13:59:29 +00002271 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002272 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002273
Martin v. Löwisa9656492003-03-30 08:44:58 +00002274#ifdef WITH_THREAD
Neal Norwitz12e22172003-03-03 21:16:39 +00002275 if (!self && !tcl_lock) {
2276 /* We don't have the Tcl lock since Tcl is threaded. */
2277 PyErr_SetString(PyExc_RuntimeError,
2278 "_tkinter.deletefilehandler not supported "
2279 "for threaded Tcl");
2280 return NULL;
2281 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002282#endif
Neal Norwitz12e22172003-03-03 21:16:39 +00002283
2284 if (self) {
2285 CHECK_TCL_APPARTMENT;
2286 }
2287
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002288 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002289 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002290 return NULL;
2291
Guido van Rossuma80649b2000-03-28 20:07:05 +00002292 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002293
Barry Warsawfa701a81997-01-16 00:15:11 +00002294 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002295 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002296 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002297 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002298 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002299 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002300}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002301#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002302
Barry Warsawfa701a81997-01-16 00:15:11 +00002303
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002304/**** Tktt Object (timer token) ****/
2305
Jeremy Hylton938ace62002-07-17 16:30:39 +00002306static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002307
Guido van Rossum00d93061998-05-28 23:06:38 +00002308typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002309 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002310 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002311 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002312} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002313
2314static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002315Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002316{
Barry Warsawfa701a81997-01-16 00:15:11 +00002317 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002318 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002319
Guido van Rossum43713e52000-02-29 13:59:29 +00002320 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002321 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002322 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002323 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002324 v->token = NULL;
2325 }
2326 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002327 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002328 Py_DECREF(func);
2329 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002330 }
2331 Py_INCREF(Py_None);
2332 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002333}
2334
2335static PyMethodDef Tktt_methods[] =
2336{
Neal Norwitzb0493252002-03-31 14:44:22 +00002337 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002338 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002339};
2340
2341static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002342Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002343{
Barry Warsawfa701a81997-01-16 00:15:11 +00002344 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002345
Guido van Rossumb18618d2000-05-03 23:44:39 +00002346 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002347 if (v == NULL)
2348 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002349
Guido van Rossum00d93061998-05-28 23:06:38 +00002350 Py_INCREF(func);
2351 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002352 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002353
2354 /* Extra reference, deleted when called or when handler is deleted */
2355 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002356 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002357}
2358
2359static void
Fred Drake509d79a2000-07-08 04:04:38 +00002360Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002361{
Guido van Rossum00d93061998-05-28 23:06:38 +00002362 TkttObject *v = (TkttObject *)self;
2363 PyObject *func = v->func;
2364
2365 Py_XDECREF(func);
2366
Guido van Rossumb18618d2000-05-03 23:44:39 +00002367 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002368}
2369
Guido van Rossum597ac201998-05-12 14:36:19 +00002370static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002371Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002372{
Barry Warsawfa701a81997-01-16 00:15:11 +00002373 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002374 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002375
Tim Peters885d4572001-11-28 20:27:42 +00002376 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002377 v->func == NULL ? ", handler deleted" : "");
Walter Dörwald1ab83302007-05-18 17:15:44 +00002378 return PyUnicode_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002379}
2380
2381static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002382Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002383{
Barry Warsawfa701a81997-01-16 00:15:11 +00002384 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002385}
2386
2387static PyTypeObject Tktt_Type =
2388{
Guido van Rossum35d43371997-08-02 00:09:09 +00002389 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002390 0, /*ob_size */
2391 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002392 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002393 0, /*tp_itemsize */
2394 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002395 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00002396 Tktt_GetAttr, /*tp_getattr */
2397 0, /*tp_setattr */
2398 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00002399 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002400 0, /*tp_as_number */
2401 0, /*tp_as_sequence */
2402 0, /*tp_as_mapping */
2403 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002404};
2405
Barry Warsawfa701a81997-01-16 00:15:11 +00002406
2407
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002408/** Timer Handler **/
2409
2410static void
Fred Drake509d79a2000-07-08 04:04:38 +00002411TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002412{
Guido van Rossum00d93061998-05-28 23:06:38 +00002413 TkttObject *v = (TkttObject *)clientData;
2414 PyObject *func = v->func;
2415 PyObject *res;
2416
2417 if (func == NULL)
2418 return;
2419
2420 v->func = NULL;
2421
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002422 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002423
2424 res = PyEval_CallObject(func, NULL);
2425 Py_DECREF(func);
2426 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002427
Barry Warsawfa701a81997-01-16 00:15:11 +00002428 if (res == NULL) {
2429 errorInCmd = 1;
2430 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2431 }
2432 else
2433 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002434
2435 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002436}
2437
2438static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002439Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002440{
Barry Warsawfa701a81997-01-16 00:15:11 +00002441 int milliseconds;
2442 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002443 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002444
Guido van Rossum2834b972000-10-06 16:58:26 +00002445 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2446 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002447 return NULL;
2448 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002449 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002450 return NULL;
2451 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002452
Martin v. Löwisa9656492003-03-30 08:44:58 +00002453#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002454 if (!self && !tcl_lock) {
2455 /* We don't have the Tcl lock since Tcl is threaded. */
2456 PyErr_SetString(PyExc_RuntimeError,
2457 "_tkinter.createtimerhandler not supported "
2458 "for threaded Tcl");
2459 return NULL;
2460 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002461#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002462
2463 if (self) {
2464 CHECK_TCL_APPARTMENT;
2465 }
2466
Guido van Rossum00d93061998-05-28 23:06:38 +00002467 v = Tktt_New(func);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002468 if (v) {
2469 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2470 (ClientData)v);
2471 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002472
Guido van Rossum00d93061998-05-28 23:06:38 +00002473 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002474}
2475
Barry Warsawfa701a81997-01-16 00:15:11 +00002476
Guido van Rossum18468821994-06-20 07:49:28 +00002477/** Event Loop **/
2478
Guido van Rossum18468821994-06-20 07:49:28 +00002479static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002480Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002481{
Barry Warsawfa701a81997-01-16 00:15:11 +00002482 int threshold = 0;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002483 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002484#ifdef WITH_THREAD
2485 PyThreadState *tstate = PyThreadState_Get();
2486#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002487
Guido van Rossum43713e52000-02-29 13:59:29 +00002488 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002489 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002490
Martin v. Löwisa9656492003-03-30 08:44:58 +00002491#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002492 if (!self && !tcl_lock) {
2493 /* We don't have the Tcl lock since Tcl is threaded. */
2494 PyErr_SetString(PyExc_RuntimeError,
2495 "_tkinter.mainloop not supported "
2496 "for threaded Tcl");
2497 return NULL;
2498 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002499#endif
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002500
2501 if (self) {
2502 CHECK_TCL_APPARTMENT;
2503 self->dispatching = 1;
2504 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002505
Barry Warsawfa701a81997-01-16 00:15:11 +00002506 quitMainLoop = 0;
2507 while (Tk_GetNumMainWindows() > threshold &&
2508 !quitMainLoop &&
2509 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002510 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002511 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002512
2513#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002514 if (self && self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002515 /* Allow other Python threads to run. */
2516 ENTER_TCL
2517 result = Tcl_DoOneEvent(0);
2518 LEAVE_TCL
2519 }
2520 else {
2521 Py_BEGIN_ALLOW_THREADS
2522 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2523 tcl_tstate = tstate;
2524 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2525 tcl_tstate = NULL;
2526 if(tcl_lock)PyThread_release_lock(tcl_lock);
2527 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002528 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002529 Py_END_ALLOW_THREADS
2530 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002531#else
2532 result = Tcl_DoOneEvent(0);
2533#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002534
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002535 if (PyErr_CheckSignals() != 0) {
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002536 if (self)
2537 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002538 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002539 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002540 if (result < 0)
2541 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002542 }
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002543 if (self)
2544 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002545 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002546
Barry Warsawfa701a81997-01-16 00:15:11 +00002547 if (errorInCmd) {
2548 errorInCmd = 0;
2549 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2550 excInCmd = valInCmd = trbInCmd = NULL;
2551 return NULL;
2552 }
2553 Py_INCREF(Py_None);
2554 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002555}
2556
2557static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002558Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002559{
Guido van Rossum35d43371997-08-02 00:09:09 +00002560 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002561 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002562
Guido van Rossum43713e52000-02-29 13:59:29 +00002563 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002564 return NULL;
2565
Guido van Rossum00d93061998-05-28 23:06:38 +00002566 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002567 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002568 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002569 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002570}
2571
2572static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002573Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002574{
2575
Guido van Rossum43713e52000-02-29 13:59:29 +00002576 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002577 return NULL;
2578
2579 quitMainLoop = 1;
2580 Py_INCREF(Py_None);
2581 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002582}
2583
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002584static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002585Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002586{
2587
Guido van Rossum43713e52000-02-29 13:59:29 +00002588 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002589 return NULL;
2590
2591 return PyInt_FromLong((long)Tkapp_Interp(self));
2592}
2593
David Aschere2b4b322004-02-18 05:59:53 +00002594static PyObject *
2595Tkapp_TkInit(PyObject *self, PyObject *args)
2596{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002597 static int has_failed;
David Aschere2b4b322004-02-18 05:59:53 +00002598 Tcl_Interp *interp = Tkapp_Interp(self);
Neal Norwitz44dbae82004-02-19 02:44:22 +00002599 Tk_Window main_window;
David Aschere2b4b322004-02-18 05:59:53 +00002600 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002601 int err;
Neal Norwitz44dbae82004-02-19 02:44:22 +00002602 main_window = Tk_MainWindow(interp);
David Aschere2b4b322004-02-18 05:59:53 +00002603
Thomas Wouters477c8d52006-05-27 19:21:47 +00002604 /* In all current versions of Tk (including 8.4.13), Tk_Init
2605 deadlocks on the second call when the first call failed.
2606 To avoid the deadlock, we just refuse the second call through
2607 a static variable. */
2608 if (has_failed) {
2609 PyErr_SetString(Tkinter_TclError,
2610 "Calling Tk_Init again after a previous call failed might deadlock");
2611 return NULL;
2612 }
2613
David Aschere2b4b322004-02-18 05:59:53 +00002614 /* We want to guard against calling Tk_Init() multiple times */
2615 CHECK_TCL_APPARTMENT;
2616 ENTER_TCL
2617 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2618 ENTER_OVERLAP
2619 if (err == TCL_ERROR) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002620 /* This sets an exception, but we cannot return right
2621 away because we need to exit the overlap first. */
2622 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002623 } else {
2624 _tk_exists = Tkapp_Result(self);
2625 }
2626 LEAVE_OVERLAP_TCL
2627 if (err == TCL_ERROR) {
2628 return NULL;
2629 }
2630 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2631 if (Tk_Init(interp) == TCL_ERROR) {
2632 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
Thomas Wouters477c8d52006-05-27 19:21:47 +00002633 has_failed = 1;
David Aschere2b4b322004-02-18 05:59:53 +00002634 return NULL;
2635 }
2636 }
2637 Py_INCREF(Py_None);
2638 return Py_None;
2639}
Barry Warsawfa701a81997-01-16 00:15:11 +00002640
Martin v. Löwisffad6332002-11-26 09:28:05 +00002641static PyObject *
2642Tkapp_WantObjects(PyObject *self, PyObject *args)
2643{
2644
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002645 int wantobjects = -1;
2646 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002647 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002648 if (wantobjects == -1)
2649 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002650 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002651
2652 Py_INCREF(Py_None);
2653 return Py_None;
2654}
2655
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002656static PyObject *
2657Tkapp_WillDispatch(PyObject *self, PyObject *args)
2658{
2659
2660 ((TkappObject*)self)->dispatching = 1;
2661
2662 Py_INCREF(Py_None);
2663 return Py_None;
2664}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002665
Barry Warsawfa701a81997-01-16 00:15:11 +00002666
Guido van Rossum18468821994-06-20 07:49:28 +00002667/**** Tkapp Method List ****/
2668
2669static PyMethodDef Tkapp_methods[] =
2670{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002671 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002672 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002673 {"call", Tkapp_Call, METH_OLDARGS},
2674 {"globalcall", Tkapp_GlobalCall, METH_OLDARGS},
2675 {"eval", Tkapp_Eval, METH_VARARGS},
2676 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2677 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2678 {"record", Tkapp_Record, METH_VARARGS},
2679 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2680 {"setvar", Tkapp_SetVar, METH_VARARGS},
2681 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2682 {"getvar", Tkapp_GetVar, METH_VARARGS},
2683 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2684 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2685 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2686 {"getint", Tkapp_GetInt, METH_VARARGS},
2687 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2688 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2689 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2690 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2691 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2692 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2693 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2694 {"split", Tkapp_Split, METH_VARARGS},
2695 {"merge", Tkapp_Merge, METH_OLDARGS},
2696 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2697 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002698#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002699 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2700 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002701#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002702 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2703 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2704 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2705 {"quit", Tkapp_Quit, METH_VARARGS},
2706 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002707 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002708 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002709};
2710
Barry Warsawfa701a81997-01-16 00:15:11 +00002711
2712
Guido van Rossum18468821994-06-20 07:49:28 +00002713/**** Tkapp Type Methods ****/
2714
2715static void
Fred Drake509d79a2000-07-08 04:04:38 +00002716Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002717{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002718 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002719 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002720 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002721 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002722 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002723 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002724}
2725
2726static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002727Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002728{
Guido van Rossum35d43371997-08-02 00:09:09 +00002729 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002730}
2731
2732static PyTypeObject Tkapp_Type =
2733{
Guido van Rossum35d43371997-08-02 00:09:09 +00002734 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002735 0, /*ob_size */
2736 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002737 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002738 0, /*tp_itemsize */
2739 Tkapp_Dealloc, /*tp_dealloc */
2740 0, /*tp_print */
2741 Tkapp_GetAttr, /*tp_getattr */
2742 0, /*tp_setattr */
2743 0, /*tp_compare */
2744 0, /*tp_repr */
2745 0, /*tp_as_number */
2746 0, /*tp_as_sequence */
2747 0, /*tp_as_mapping */
2748 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002749};
2750
Barry Warsawfa701a81997-01-16 00:15:11 +00002751
2752
Guido van Rossum18468821994-06-20 07:49:28 +00002753/**** Tkinter Module ****/
2754
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002755typedef struct {
2756 PyObject* tuple;
2757 int size; /* current size */
2758 int maxsize; /* allocated size */
2759} FlattenContext;
2760
2761static int
2762_bump(FlattenContext* context, int size)
2763{
Guido van Rossum2834b972000-10-06 16:58:26 +00002764 /* expand tuple to hold (at least) size new items.
2765 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002766
2767 int maxsize = context->maxsize * 2;
2768
2769 if (maxsize < context->size + size)
2770 maxsize = context->size + size;
2771
2772 context->maxsize = maxsize;
2773
Tim Peters4324aa32001-05-28 22:30:08 +00002774 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002775}
2776
2777static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002778_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002779{
2780 /* add tuple or list to argument tuple (recursively) */
2781
2782 int i, size;
2783
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002784 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002785 PyErr_SetString(PyExc_ValueError,
2786 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002787 return 0;
2788 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002789 size = PyList_GET_SIZE(item);
2790 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002791 if (context->size + size > context->maxsize &&
2792 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002793 return 0;
2794 /* copy items to output tuple */
2795 for (i = 0; i < size; i++) {
2796 PyObject *o = PyList_GET_ITEM(item, i);
2797 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002798 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002799 return 0;
2800 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002801 if (context->size + 1 > context->maxsize &&
2802 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002803 return 0;
2804 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002805 PyTuple_SET_ITEM(context->tuple,
2806 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002807 }
2808 }
2809 } else if (PyTuple_Check(item)) {
2810 /* same, for tuples */
2811 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002812 if (context->size + size > context->maxsize &&
2813 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002814 return 0;
2815 for (i = 0; i < size; i++) {
2816 PyObject *o = PyTuple_GET_ITEM(item, i);
2817 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002818 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002819 return 0;
2820 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002821 if (context->size + 1 > context->maxsize &&
2822 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002823 return 0;
2824 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002825 PyTuple_SET_ITEM(context->tuple,
2826 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002827 }
2828 }
2829 } else {
2830 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2831 return 0;
2832 }
2833 return 1;
2834}
2835
2836static PyObject *
2837Tkinter_Flatten(PyObject* self, PyObject* args)
2838{
2839 FlattenContext context;
2840 PyObject* item;
2841
2842 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2843 return NULL;
2844
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002845 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002846 if (context.maxsize <= 0)
2847 return PyTuple_New(0);
2848
2849 context.tuple = PyTuple_New(context.maxsize);
2850 if (!context.tuple)
2851 return NULL;
2852
2853 context.size = 0;
2854
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002855 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002856 return NULL;
2857
Tim Peters4324aa32001-05-28 22:30:08 +00002858 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002859 return NULL;
2860
2861 return context.tuple;
2862}
2863
Guido van Rossum18468821994-06-20 07:49:28 +00002864static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002865Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002866{
Barry Warsawfa701a81997-01-16 00:15:11 +00002867 char *screenName = NULL;
2868 char *baseName = NULL;
2869 char *className = NULL;
2870 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002871 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002872 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002873 int sync = 0; /* pass -sync to wish */
2874 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002875
Guido van Rossum35d43371997-08-02 00:09:09 +00002876 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002877 if (baseName != NULL)
2878 baseName++;
2879 else
2880 baseName = Py_GetProgramName();
2881 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002882
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002883 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002884 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002885 &interactive, &wantobjects, &wantTk,
2886 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00002887 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002888
Barry Warsawfa701a81997-01-16 00:15:11 +00002889 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002890 interactive, wantobjects, wantTk,
2891 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002892}
2893
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002894static PyObject *
2895Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2896{
2897 int new_val;
2898 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2899 return NULL;
2900 if (new_val < 0) {
2901 PyErr_SetString(PyExc_ValueError,
2902 "busywaitinterval must be >= 0");
2903 return NULL;
2904 }
2905 Tkinter_busywaitinterval = new_val;
2906 Py_INCREF(Py_None);
2907 return Py_None;
2908}
2909
2910static char setbusywaitinterval_doc[] =
2911"setbusywaitinterval(n) -> None\n\
2912\n\
2913Set the busy-wait interval in milliseconds between successive\n\
2914calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2915It should be set to a divisor of the maximum time between\n\
2916frames in an animation.";
2917
2918static PyObject *
2919Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2920{
2921 return PyInt_FromLong(Tkinter_busywaitinterval);
2922}
2923
2924static char getbusywaitinterval_doc[] =
2925"getbusywaitinterval() -> int\n\
2926\n\
2927Return the current busy-wait interval between successive\n\
2928calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2929
Guido van Rossum18468821994-06-20 07:49:28 +00002930static PyMethodDef moduleMethods[] =
2931{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002932 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2933 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002934#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002935 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2936 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002937#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002938 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2939 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2940 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2941 {"quit", Tkapp_Quit, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002942 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2943 setbusywaitinterval_doc},
2944 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2945 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00002946 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002947};
2948
Guido van Rossum7bf15641998-05-22 18:28:17 +00002949#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002950
2951static int stdin_ready = 0;
2952
Guido van Rossumad4db171998-06-13 13:56:28 +00002953#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002954static void
Fred Drake509d79a2000-07-08 04:04:38 +00002955MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002956{
2957 stdin_ready = 1;
2958}
Guido van Rossumad4db171998-06-13 13:56:28 +00002959#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002960
Martin v. Löwisa9656492003-03-30 08:44:58 +00002961#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002962static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002963#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002964
Guido van Rossum18468821994-06-20 07:49:28 +00002965static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002966EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002967{
Guido van Rossumad4db171998-06-13 13:56:28 +00002968#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002969 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002970#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002971#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002972 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002973#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002974 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002975 errorInCmd = 0;
2976#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002977 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002978 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002979#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002980 while (!errorInCmd && !stdin_ready) {
2981 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002982#ifdef MS_WINDOWS
2983 if (_kbhit()) {
2984 stdin_ready = 1;
2985 break;
2986 }
2987#endif
2988#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002989 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002990 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002991 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002992
Guido van Rossum00d93061998-05-28 23:06:38 +00002993 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002994
2995 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002996 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002997 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002998 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00002999 Py_END_ALLOW_THREADS
3000#else
3001 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003002#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003003
3004 if (result < 0)
3005 break;
3006 }
Guido van Rossumad4db171998-06-13 13:56:28 +00003007#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00003008 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00003009#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003010 if (errorInCmd) {
3011 errorInCmd = 0;
3012 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3013 excInCmd = valInCmd = trbInCmd = NULL;
3014 PyErr_Print();
3015 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003016#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003017 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003018#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003019 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00003020}
Guido van Rossum18468821994-06-20 07:49:28 +00003021
Guido van Rossum00d93061998-05-28 23:06:38 +00003022#endif
3023
Guido van Rossum7bf15641998-05-22 18:28:17 +00003024static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003025EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003026{
Guido van Rossum00d93061998-05-28 23:06:38 +00003027#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003028 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003029#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003030 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003031#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003032 PyOS_InputHook = EventHook;
3033 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003034#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003035}
3036
3037static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003038DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003039{
Guido van Rossum00d93061998-05-28 23:06:38 +00003040#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003041 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3042 PyOS_InputHook = NULL;
3043 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003044#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003045}
3046
Barry Warsawfa701a81997-01-16 00:15:11 +00003047
3048/* all errors will be checked in one fell swoop in init_tkinter() */
3049static void
Fred Drake509d79a2000-07-08 04:04:38 +00003050ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003051{
3052 PyObject *v = PyInt_FromLong(val);
3053 if (v) {
3054 PyDict_SetItemString(d, name, v);
3055 Py_DECREF(v);
3056 }
3057}
3058static void
Fred Drake509d79a2000-07-08 04:04:38 +00003059ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003060{
3061 PyObject *v = PyString_FromString(val);
3062 if (v) {
3063 PyDict_SetItemString(d, name, v);
3064 Py_DECREF(v);
3065 }
3066}
3067
3068
Mark Hammond62b1ab12002-07-23 06:31:15 +00003069PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003070init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003071{
Barry Warsawfa701a81997-01-16 00:15:11 +00003072 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00003073
Barry Warsawfa701a81997-01-16 00:15:11 +00003074 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00003075
3076#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003077 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003078#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003079
Barry Warsawfa701a81997-01-16 00:15:11 +00003080 m = Py_InitModule("_tkinter", moduleMethods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003081 if (m == NULL)
3082 return;
Guido van Rossum18468821994-06-20 07:49:28 +00003083
Barry Warsawfa701a81997-01-16 00:15:11 +00003084 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003085 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003086 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003087
Guido van Rossum35d43371997-08-02 00:09:09 +00003088 ins_long(d, "READABLE", TCL_READABLE);
3089 ins_long(d, "WRITABLE", TCL_WRITABLE);
3090 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3091 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3092 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3093 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3094 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3095 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3096 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003097 ins_string(d, "TK_VERSION", TK_VERSION);
3098 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003099
Guido van Rossum83551bf1997-09-13 00:44:23 +00003100 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003101
3102 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003103 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3104
Martin v. Löwisffad6332002-11-26 09:28:05 +00003105 PyTclObject_Type.ob_type = &PyType_Type;
3106 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003107
3108#ifdef TK_AQUA
3109 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3110 * start waking up. Note that Tcl_FindExecutable will do this, this
3111 * code must be above it! The original warning from
3112 * tkMacOSXAppInit.c is copied below.
3113 *
3114 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3115 * Tcl interpreter for now. It probably should work to do this
3116 * in the other order, but for now it doesn't seem to.
3117 *
3118 */
3119 Tk_MacOSXSetupTkNotifier();
3120#endif
3121
3122
Guido van Rossume187b0e2000-03-27 21:46:29 +00003123 /* This helps the dynamic loader; in Unicode aware Tcl versions
3124 it also helps Tcl find its encodings. */
3125 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00003126
Barry Warsawfa701a81997-01-16 00:15:11 +00003127 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003128 return;
3129
Guido van Rossum43ff8681998-07-14 18:02:13 +00003130#if 0
3131 /* This was not a good idea; through <Destroy> bindings,
3132 Tcl_Finalize() may invoke Python code but at that point the
3133 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003134 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003135#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003136
Guido van Rossum18468821994-06-20 07:49:28 +00003137}