blob: 8a702d6daea853a310091b576242814af566cf2a [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);
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000340#ifdef Py_USING_UNICODE
Guido van Rossum2834b972000-10-06 16:58:26 +0000341 else if (PyUnicode_Check(value)) {
342 PyObject *v = PyUnicode_AsUTF8String(value);
343 if (v == NULL)
344 return NULL;
345 if (PyList_Append(tmp, v) != 0) {
346 Py_DECREF(v);
347 return NULL;
348 }
349 Py_DECREF(v);
350 return PyString_AsString(v);
351 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000352#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000353 else {
354 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000355 if (v == NULL)
356 return NULL;
357 if (PyList_Append(tmp, v) != 0) {
358 Py_DECREF(v);
359 return NULL;
360 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000361 Py_DECREF(v);
362 return PyString_AsString(v);
363 }
Guido van Rossum18468821994-06-20 07:49:28 +0000364}
365
Barry Warsawfa701a81997-01-16 00:15:11 +0000366
367
Guido van Rossum18468821994-06-20 07:49:28 +0000368#define ARGSZ 64
369
370static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000371Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000372{
Barry Warsawfa701a81997-01-16 00:15:11 +0000373 PyObject *tmp = NULL;
374 char *argvStore[ARGSZ];
375 char **argv = NULL;
376 int fvStore[ARGSZ];
377 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000378 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000379 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000380
Barry Warsawfa701a81997-01-16 00:15:11 +0000381 if (!(tmp = PyList_New(0)))
382 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 argv = argvStore;
385 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000386
Barry Warsawfa701a81997-01-16 00:15:11 +0000387 if (args == NULL)
388 argc = 0;
389
390 else if (!PyTuple_Check(args)) {
391 argc = 1;
392 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000393 if (!(argv[0] = AsString(args, tmp)))
394 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000395 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000396 else {
397 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000398
Barry Warsawfa701a81997-01-16 00:15:11 +0000399 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000400 argv = (char **)ckalloc(argc * sizeof(char *));
401 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000402 if (argv == NULL || fv == NULL) {
403 PyErr_NoMemory();
404 goto finally;
405 }
406 }
407
408 for (i = 0; i < argc; i++) {
409 PyObject *v = PyTuple_GetItem(args, i);
410 if (PyTuple_Check(v)) {
411 fv[i] = 1;
412 if (!(argv[i] = Merge(v)))
413 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000414 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000415 }
416 else if (v == Py_None) {
417 argc = i;
418 break;
419 }
420 else {
421 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000422 if (!(argv[i] = AsString(v, tmp)))
423 goto finally;
424 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000425 }
426 }
Guido van Rossum18468821994-06-20 07:49:28 +0000427 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000429 if (res == NULL)
430 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000431
Barry Warsawfa701a81997-01-16 00:15:11 +0000432 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000433 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000434 if (fv[i]) {
435 ckfree(argv[i]);
436 }
437 if (argv != argvStore)
438 ckfree(FREECAST argv);
439 if (fv != fvStore)
440 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000441
Barry Warsawfa701a81997-01-16 00:15:11 +0000442 Py_DECREF(tmp);
443 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000444}
445
Barry Warsawfa701a81997-01-16 00:15:11 +0000446
447
Guido van Rossum18468821994-06-20 07:49:28 +0000448static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000449Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000450{
Barry Warsawfa701a81997-01-16 00:15:11 +0000451 int argc;
452 char **argv;
453 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000454
Barry Warsawfa701a81997-01-16 00:15:11 +0000455 if (list == NULL) {
456 Py_INCREF(Py_None);
457 return Py_None;
458 }
Guido van Rossum18468821994-06-20 07:49:28 +0000459
Guido van Rossum00d93061998-05-28 23:06:38 +0000460 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000461 /* Not a list.
462 * Could be a quoted string containing funnies, e.g. {"}.
463 * Return the string itself.
464 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000465 return PyString_FromString(list);
466 }
Guido van Rossum18468821994-06-20 07:49:28 +0000467
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 if (argc == 0)
469 v = PyString_FromString("");
470 else if (argc == 1)
471 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000472 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000473 int i;
474 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000475
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000477 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000478 Py_DECREF(v);
479 v = NULL;
480 break;
481 }
482 PyTuple_SetItem(v, i, w);
483 }
484 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000485 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000486 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000487}
488
Martin v. Löwisffad6332002-11-26 09:28:05 +0000489/* In some cases, Tcl will still return strings that are supposed to be
490 lists. SplitObj walks through a nested tuple, finding string objects that
491 need to be split. */
492
493PyObject *
494SplitObj(PyObject *arg)
495{
496 if (PyTuple_Check(arg)) {
497 int i, size;
498 PyObject *elem, *newelem, *result;
499
500 size = PyTuple_Size(arg);
501 result = NULL;
502 /* Recursively invoke SplitObj for all tuple items.
503 If this does not return a new object, no action is
504 needed. */
505 for(i = 0; i < size; i++) {
506 elem = PyTuple_GetItem(arg, i);
507 newelem = SplitObj(elem);
508 if (!newelem) {
509 Py_XDECREF(result);
510 return NULL;
511 }
512 if (!result) {
513 int k;
514 if (newelem == elem) {
515 Py_DECREF(newelem);
516 continue;
517 }
518 result = PyTuple_New(size);
519 if (!result)
520 return NULL;
521 for(k = 0; k < i; k++) {
522 elem = PyTuple_GetItem(arg, k);
523 Py_INCREF(elem);
524 PyTuple_SetItem(result, k, elem);
525 }
526 }
527 PyTuple_SetItem(result, i, newelem);
528 }
529 if (result)
530 return result;
531 /* Fall through, returning arg. */
532 }
533 else if (PyString_Check(arg)) {
534 int argc;
535 char **argv;
536 char *list = PyString_AsString(arg);
537
538 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
539 Py_INCREF(arg);
540 return arg;
541 }
542 Tcl_Free(FREECAST argv);
543 if (argc > 1)
544 return Split(PyString_AsString(arg));
545 /* Fall through, returning arg. */
546 }
547 Py_INCREF(arg);
548 return arg;
549}
Barry Warsawfa701a81997-01-16 00:15:11 +0000550
551
Guido van Rossum18468821994-06-20 07:49:28 +0000552/**** Tkapp Object ****/
553
554#ifndef WITH_APPINIT
555int
Fred Drake509d79a2000-07-08 04:04:38 +0000556Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000557{
Barry Warsawfa701a81997-01-16 00:15:11 +0000558 Tk_Window main;
David Aschere2b4b322004-02-18 05:59:53 +0000559 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000560
Barry Warsawfa701a81997-01-16 00:15:11 +0000561 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000562 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000563 return TCL_ERROR;
564 }
David Aschere2b4b322004-02-18 05:59:53 +0000565 _tkinter_skip_tk_init = Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
566 if (_tkinter_skip_tk_init == NULL || strcmp(_tkinter_skip_tk_init, "1") != 0) {
567 main = Tk_MainWindow(interp);
568 if (Tk_Init(interp) == TCL_ERROR) {
569 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
570 return TCL_ERROR;
571 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000572 }
573 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000574}
575#endif /* !WITH_APPINIT */
576
Guido van Rossum18468821994-06-20 07:49:28 +0000577
Barry Warsawfa701a81997-01-16 00:15:11 +0000578
579
580/* Initialize the Tk application; see the `main' function in
581 * `tkMain.c'.
582 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000583
Thomas Wouters58d05102000-07-24 14:43:35 +0000584static void EnableEventHook(void); /* Forward */
585static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000586
Barry Warsawfa701a81997-01-16 00:15:11 +0000587static TkappObject *
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000588Tkapp_New(char *screenName, char *baseName, char *className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000589 int interactive, int wantobjects, int wantTk, int sync, char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000590{
591 TkappObject *v;
592 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000593
Guido van Rossumb18618d2000-05-03 23:44:39 +0000594 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000595 if (v == NULL)
596 return NULL;
597
598 v->interp = Tcl_CreateInterp();
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000599 v->wantobjects = wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000600 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
601 TCL_GLOBAL_ONLY) != NULL;
602 v->thread_id = Tcl_GetCurrentThread();
603 v->dispatching = 0;
604
605#ifndef TCL_THREADS
606 if (v->threaded) {
607 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
608 Py_DECREF(v);
609 return 0;
610 }
611#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000612#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000613 if (v->threaded && tcl_lock) {
614 /* If Tcl is threaded, we don't need the lock. */
615 PyThread_free_lock(tcl_lock);
616 tcl_lock = NULL;
617 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000618#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000619
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000620 v->BooleanType = Tcl_GetObjType("boolean");
621 v->ByteArrayType = Tcl_GetObjType("bytearray");
622 v->DoubleType = Tcl_GetObjType("double");
623 v->IntType = Tcl_GetObjType("int");
624 v->ListType = Tcl_GetObjType("list");
625 v->ProcBodyType = Tcl_GetObjType("procbody");
626 v->StringType = Tcl_GetObjType("string");
627
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000628 /* Delete the 'exit' command, which can screw things up */
629 Tcl_DeleteCommand(v->interp, "exit");
630
Barry Warsawfa701a81997-01-16 00:15:11 +0000631 if (screenName != NULL)
632 Tcl_SetVar2(v->interp, "env", "DISPLAY",
633 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000634
Barry Warsawfa701a81997-01-16 00:15:11 +0000635 if (interactive)
636 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
637 else
638 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000639
Barry Warsawfa701a81997-01-16 00:15:11 +0000640 /* This is used to get the application class for Tk 4.1 and up */
641 argv0 = (char*)ckalloc(strlen(className) + 1);
642 if (!argv0) {
643 PyErr_NoMemory();
644 Py_DECREF(v);
645 return NULL;
646 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000647
Barry Warsawfa701a81997-01-16 00:15:11 +0000648 strcpy(argv0, className);
Neal Norwitz9dbc7dd2005-12-19 06:08:59 +0000649 if (isupper(Py_CHARMASK(argv0[0])))
Neal Norwitz65c05b22006-04-10 02:17:47 +0000650 argv0[0] = tolower(Py_CHARMASK(argv0[0]));
Barry Warsawfa701a81997-01-16 00:15:11 +0000651 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
652 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000653
David Aschere2b4b322004-02-18 05:59:53 +0000654 if (! wantTk) {
655 Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
656 }
657
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000658 /* some initial arguments need to be in argv */
659 if (sync || use) {
Tim Peters51fa3b72004-08-04 02:16:48 +0000660 char *args;
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000661 int len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000662
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000663 if (sync)
664 len += sizeof "-sync";
665 if (use)
666 len += strlen(use) + sizeof "-use ";
667
Tim Peters51fa3b72004-08-04 02:16:48 +0000668 args = (char*)ckalloc(len);
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000669 if (!args) {
670 PyErr_NoMemory();
671 Py_DECREF(v);
672 return NULL;
673 }
674
675 args[0] = '\0';
676 if (sync)
677 strcat(args, "-sync");
678 if (use) {
679 if (sync)
680 strcat(args, " ");
681 strcat(args, "-use ");
682 strcat(args, use);
683 }
684
685 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
686 ckfree(args);
687 }
688
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000689 if (Tcl_AppInit(v->interp) != TCL_OK) {
690 PyObject *result = Tkinter_Error((PyObject *)v);
691 Py_DECREF((PyObject *)v);
692 return (TkappObject *)result;
693 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000694
Guido van Rossum7bf15641998-05-22 18:28:17 +0000695 EnableEventHook();
696
Barry Warsawfa701a81997-01-16 00:15:11 +0000697 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000698}
699
Barry Warsawfa701a81997-01-16 00:15:11 +0000700
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000701static void
702Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
703 Tcl_Condition *cond, Tcl_Mutex *mutex)
704{
705 Py_BEGIN_ALLOW_THREADS;
706 Tcl_MutexLock(mutex);
707 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
708 Tcl_ThreadAlert(self->thread_id);
709 Tcl_ConditionWait(cond, mutex, NULL);
710 Tcl_MutexUnlock(mutex);
711 Py_END_ALLOW_THREADS
712}
713
Barry Warsawfa701a81997-01-16 00:15:11 +0000714
Guido van Rossum18468821994-06-20 07:49:28 +0000715/** Tcl Eval **/
716
Martin v. Löwisffad6332002-11-26 09:28:05 +0000717typedef struct {
718 PyObject_HEAD
719 Tcl_Obj *value;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000720 PyObject *string; /* This cannot cause cycles. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000721} PyTclObject;
722
723staticforward PyTypeObject PyTclObject_Type;
724#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
725
726static PyObject *
727newPyTclObject(Tcl_Obj *arg)
728{
729 PyTclObject *self;
730 self = PyObject_New(PyTclObject, &PyTclObject_Type);
731 if (self == NULL)
732 return NULL;
733 Tcl_IncrRefCount(arg);
734 self->value = arg;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000735 self->string = NULL;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000736 return (PyObject*)self;
737}
738
739static void
740PyTclObject_dealloc(PyTclObject *self)
741{
742 Tcl_DecrRefCount(self->value);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000743 Py_XDECREF(self->string);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000744 PyObject_Del(self);
745}
746
747static PyObject *
748PyTclObject_str(PyTclObject *self)
749{
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000750 if (self->string && PyString_Check(self->string)) {
751 Py_INCREF(self->string);
752 return self->string;
753 }
754 /* XXX Could cache value if it is an ASCII string. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000755 return PyString_FromString(Tcl_GetString(self->value));
756}
757
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000758static char*
759PyTclObject_TclString(PyObject *self)
760{
761 return Tcl_GetString(((PyTclObject*)self)->value);
762}
763
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000764/* Like _str, but create Unicode if necessary. */
Martin v. Löwis39195712003-01-04 00:33:13 +0000765PyDoc_STRVAR(PyTclObject_string__doc__,
766"the string representation of this object, either as string or Unicode");
767
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000768static PyObject *
769PyTclObject_string(PyTclObject *self, void *ignored)
770{
771 char *s;
772 int i, len;
773 if (!self->string) {
774 s = Tcl_GetStringFromObj(self->value, &len);
775 for (i = 0; i < len; i++)
776 if (s[i] & 0x80)
777 break;
778#ifdef Py_USING_UNICODE
779 if (i == len)
780 /* It is an ASCII string. */
781 self->string = PyString_FromStringAndSize(s, len);
782 else {
783 self->string = PyUnicode_DecodeUTF8(s, len, "strict");
784 if (!self->string) {
785 PyErr_Clear();
786 self->string = PyString_FromStringAndSize(s, len);
787 }
788 }
789#else
790 self->string = PyString_FromStringAndSize(s, len);
791#endif
792 if (!self->string)
793 return NULL;
794 }
795 Py_INCREF(self->string);
796 return self->string;
797}
798
799#ifdef Py_USING_UNICODE
Martin v. Löwis39195712003-01-04 00:33:13 +0000800PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode");
801
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000802static PyObject *
803PyTclObject_unicode(PyTclObject *self, void *ignored)
804{
805 char *s;
806 int len;
807 if (self->string && PyUnicode_Check(self->string)) {
808 Py_INCREF(self->string);
809 return self->string;
810 }
811 /* XXX Could chache result if it is non-ASCII. */
812 s = Tcl_GetStringFromObj(self->value, &len);
813 return PyUnicode_DecodeUTF8(s, len, "strict");
814}
815#endif
816
Martin v. Löwisffad6332002-11-26 09:28:05 +0000817static PyObject *
818PyTclObject_repr(PyTclObject *self)
819{
820 char buf[50];
Martin v. Löwisfba73692004-11-13 11:13:35 +0000821 PyOS_snprintf(buf, 50, "<%s object at %p>",
822 self->value->typePtr->name, self->value);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000823 return PyString_FromString(buf);
824}
825
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000826static int
827PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
828{
829 int res;
830 res = strcmp(Tcl_GetString(self->value),
831 Tcl_GetString(other->value));
832 if (res < 0) return -1;
833 if (res > 0) return 1;
834 return 0;
835}
836
Martin v. Löwis39195712003-01-04 00:33:13 +0000837PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
838
Martin v. Löwisffad6332002-11-26 09:28:05 +0000839static PyObject*
840get_typename(PyTclObject* obj, void* ignored)
841{
842 return PyString_FromString(obj->value->typePtr->name);
843}
844
Martin v. Löwis39195712003-01-04 00:33:13 +0000845
Martin v. Löwisffad6332002-11-26 09:28:05 +0000846static PyGetSetDef PyTclObject_getsetlist[] = {
Martin v. Löwis39195712003-01-04 00:33:13 +0000847 {"typename", (getter)get_typename, NULL, get_typename__doc__},
848 {"string", (getter)PyTclObject_string, NULL,
849 PyTclObject_string__doc__},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000850 {0},
851};
852
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000853static PyMethodDef PyTclObject_methods[] = {
Martin v. Löwise2713be2005-03-08 15:03:08 +0000854#ifdef Py_USING_UNICODE
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000855 {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS,
Martin v. Löwis39195712003-01-04 00:33:13 +0000856 PyTclObject_unicode__doc__},
Martin v. Löwise2713be2005-03-08 15:03:08 +0000857#endif
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000858 {0}
859};
860
Martin v. Löwisffad6332002-11-26 09:28:05 +0000861statichere PyTypeObject PyTclObject_Type = {
862 PyObject_HEAD_INIT(NULL)
863 0, /*ob_size*/
864 "_tkinter.Tcl_Obj", /*tp_name*/
865 sizeof(PyTclObject), /*tp_basicsize*/
866 0, /*tp_itemsize*/
867 /* methods */
868 (destructor)PyTclObject_dealloc, /*tp_dealloc*/
869 0, /*tp_print*/
870 0, /*tp_getattr*/
871 0, /*tp_setattr*/
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000872 (cmpfunc)PyTclObject_cmp, /*tp_compare*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000873 (reprfunc)PyTclObject_repr, /*tp_repr*/
874 0, /*tp_as_number*/
875 0, /*tp_as_sequence*/
876 0, /*tp_as_mapping*/
877 0, /*tp_hash*/
878 0, /*tp_call*/
879 (reprfunc)PyTclObject_str, /*tp_str*/
Jason Tishlerfb8595d2003-01-06 12:41:26 +0000880 PyObject_GenericGetAttr,/*tp_getattro*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000881 0, /*tp_setattro*/
882 0, /*tp_as_buffer*/
883 Py_TPFLAGS_DEFAULT, /*tp_flags*/
884 0, /*tp_doc*/
885 0, /*tp_traverse*/
886 0, /*tp_clear*/
887 0, /*tp_richcompare*/
888 0, /*tp_weaklistoffset*/
889 0, /*tp_iter*/
890 0, /*tp_iternext*/
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000891 PyTclObject_methods, /*tp_methods*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000892 0, /*tp_members*/
893 PyTclObject_getsetlist, /*tp_getset*/
894 0, /*tp_base*/
895 0, /*tp_dict*/
896 0, /*tp_descr_get*/
897 0, /*tp_descr_set*/
898 0, /*tp_dictoffset*/
899 0, /*tp_init*/
900 0, /*tp_alloc*/
901 0, /*tp_new*/
902 0, /*tp_free*/
903 0, /*tp_is_gc*/
904};
905
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000906static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000907AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000908{
909 Tcl_Obj *result;
910
911 if (PyString_Check(value))
912 return Tcl_NewStringObj(PyString_AS_STRING(value),
913 PyString_GET_SIZE(value));
Martin v. Löwis70c3dda2003-01-22 09:17:38 +0000914 else if (PyBool_Check(value))
915 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000916 else if (PyInt_Check(value))
917 return Tcl_NewLongObj(PyInt_AS_LONG(value));
918 else if (PyFloat_Check(value))
919 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
920 else if (PyTuple_Check(value)) {
921 Tcl_Obj **argv = (Tcl_Obj**)
922 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
923 int i;
924 if(!argv)
925 return 0;
926 for(i=0;i<PyTuple_Size(value);i++)
927 argv[i] = AsObj(PyTuple_GetItem(value,i));
928 result = Tcl_NewListObj(PyTuple_Size(value), argv);
929 ckfree(FREECAST argv);
930 return result;
931 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000932#ifdef Py_USING_UNICODE
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000933 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000934 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
Neal Norwitz047f3c72006-06-12 02:06:42 +0000935 Py_ssize_t size = PyUnicode_GET_SIZE(value);
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000936 /* This #ifdef assumes that Tcl uses UCS-2.
937 See TCL_UTF_MAX test above. */
Martin v. Löwis6f29ff32003-04-16 20:34:55 +0000938#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
Guido van Rossum3b4a5bd2008-01-03 23:52:04 +0000939 Tcl_UniChar *outbuf = NULL;
Neal Norwitz047f3c72006-06-12 02:06:42 +0000940 Py_ssize_t i;
Guido van Rossum3b4a5bd2008-01-03 23:52:04 +0000941 size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
942 if (allocsize >= size)
943 outbuf = (Tcl_UniChar*)ckalloc(allocsize);
944 /* Else overflow occurred, and we take the next exit */
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000945 if (!outbuf) {
946 PyErr_NoMemory();
947 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000948 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000949 for (i = 0; i < size; i++) {
950 if (inbuf[i] >= 0x10000) {
951 /* Tcl doesn't do UTF-16, yet. */
952 PyErr_SetString(PyExc_ValueError,
953 "unsupported character");
954 ckfree(FREECAST outbuf);
955 return NULL;
956 }
957 outbuf[i] = inbuf[i];
958 }
959 result = Tcl_NewUnicodeObj(outbuf, size);
960 ckfree(FREECAST outbuf);
961 return result;
962#else
963 return Tcl_NewUnicodeObj(inbuf, size);
964#endif
965
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000966 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000967#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +0000968 else if(PyTclObject_Check(value)) {
969 Tcl_Obj *v = ((PyTclObject*)value)->value;
970 Tcl_IncrRefCount(v);
971 return v;
972 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000973 else {
974 PyObject *v = PyObject_Str(value);
975 if (!v)
976 return 0;
977 result = AsObj(v);
978 Py_DECREF(v);
979 return result;
980 }
981}
982
Martin v. Löwisffad6332002-11-26 09:28:05 +0000983static PyObject*
984FromObj(PyObject* tkapp, Tcl_Obj *value)
985{
986 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000987 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000988
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000989 if (value->typePtr == NULL) {
990 /* If the result contains any bytes with the top bit set,
991 it's UTF-8 and we should decode it to Unicode */
992#ifdef Py_USING_UNICODE
993 int i;
994 char *s = value->bytes;
995 int len = value->length;
996 for (i = 0; i < len; i++) {
997 if (value->bytes[i] & 0x80)
998 break;
999 }
1000
1001 if (i == value->length)
1002 result = PyString_FromStringAndSize(s, len);
1003 else {
1004 /* Convert UTF-8 to Unicode string */
1005 result = PyUnicode_DecodeUTF8(s, len, "strict");
1006 if (result == NULL) {
1007 PyErr_Clear();
1008 result = PyString_FromStringAndSize(s, len);
1009 }
1010 }
1011#else
Martin v. Löwise2713be2005-03-08 15:03:08 +00001012 result = PyString_FromStringAndSize(value->bytes, value->length);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001013#endif
1014 return result;
1015 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001016
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001017 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001018 result = value->internalRep.longValue ? Py_True : Py_False;
1019 Py_INCREF(result);
1020 return result;
1021 }
1022
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001023 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001024 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +00001025 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001026 return PyString_FromStringAndSize(data, size);
1027 }
1028
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001029 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001030 return PyFloat_FromDouble(value->internalRep.doubleValue);
1031 }
1032
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001033 if (value->typePtr == app->IntType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001034 return PyInt_FromLong(value->internalRep.longValue);
1035 }
1036
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001037 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001038 int size;
1039 int i, status;
1040 PyObject *elem;
1041 Tcl_Obj *tcl_elem;
1042
1043 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
1044 if (status == TCL_ERROR)
1045 return Tkinter_Error(tkapp);
1046 result = PyTuple_New(size);
1047 if (!result)
1048 return NULL;
1049 for (i = 0; i < size; i++) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001050 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
Martin v. Löwisffad6332002-11-26 09:28:05 +00001051 value, i, &tcl_elem);
1052 if (status == TCL_ERROR) {
1053 Py_DECREF(result);
1054 return Tkinter_Error(tkapp);
1055 }
1056 elem = FromObj(tkapp, tcl_elem);
1057 if (!elem) {
1058 Py_DECREF(result);
1059 return NULL;
1060 }
1061 PyTuple_SetItem(result, i, elem);
1062 }
1063 return result;
1064 }
1065
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001066 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001067 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +00001068 }
1069
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001070 if (value->typePtr == app->StringType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001071#ifdef Py_USING_UNICODE
Martin v. Löwis6f29ff32003-04-16 20:34:55 +00001072#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
Martin v. Löwisffad6332002-11-26 09:28:05 +00001073 PyObject *result;
1074 int size;
1075 Tcl_UniChar *input;
1076 Py_UNICODE *output;
1077
1078 size = Tcl_GetCharLength(value);
1079 result = PyUnicode_FromUnicode(NULL, size);
1080 if (!result)
1081 return NULL;
1082 input = Tcl_GetUnicode(value);
1083 output = PyUnicode_AS_UNICODE(result);
1084 while (size--)
1085 *output++ = *input++;
1086 return result;
1087#else
1088 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1089 Tcl_GetCharLength(value));
1090#endif
1091#else
1092 int size;
1093 char *c;
1094 c = Tcl_GetStringFromObj(value, &size);
1095 return PyString_FromStringAndSize(c, size);
1096#endif
1097 }
1098
1099 return newPyTclObject(value);
1100}
1101
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001102/* This mutex synchronizes inter-thread command calls. */
1103
1104TCL_DECLARE_MUTEX(call_mutex)
1105
1106typedef struct Tkapp_CallEvent {
1107 Tcl_Event ev; /* Must be first */
1108 TkappObject *self;
1109 PyObject *args;
1110 int flags;
1111 PyObject **res;
1112 PyObject **exc_type, **exc_value, **exc_tb;
1113 Tcl_Condition done;
1114} Tkapp_CallEvent;
1115
1116void
1117Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001118{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001119 int i;
1120 for (i = 0; i < objc; i++)
1121 Tcl_DecrRefCount(objv[i]);
1122 if (objv != objStore)
1123 ckfree(FREECAST objv);
1124}
Guido van Rossum18468821994-06-20 07:49:28 +00001125
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001126/* Convert Python objects to Tcl objects. This must happen in the
1127 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001128
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001129static Tcl_Obj**
1130Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1131{
1132 Tcl_Obj **objv = objStore;
Martin v. Löwis7d134952002-12-12 19:05:48 +00001133 int objc = 0, i;
Guido van Rossum212643f1998-04-29 16:22:14 +00001134 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +00001135 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001136
Guido van Rossum212643f1998-04-29 16:22:14 +00001137 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +00001138 objv[0] = AsObj(args);
1139 if (objv[0] == 0)
1140 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001141 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +00001142 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001143 }
1144 else {
Guido van Rossum632de272000-03-29 00:19:50 +00001145 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001146
Guido van Rossum632de272000-03-29 00:19:50 +00001147 if (objc > ARGSZ) {
1148 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1149 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001150 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +00001151 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +00001152 goto finally;
1153 }
1154 }
1155
Guido van Rossum632de272000-03-29 00:19:50 +00001156 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001157 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +00001158 if (v == Py_None) {
1159 objc = i;
1160 break;
1161 }
Guido van Rossum632de272000-03-29 00:19:50 +00001162 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +00001163 if (!objv[i]) {
1164 /* Reset objc, so it attempts to clear
1165 objects only up to i. */
1166 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +00001167 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001168 }
Guido van Rossum632de272000-03-29 00:19:50 +00001169 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001170 }
1171 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001172 *pobjc = objc;
1173 return objv;
1174finally:
1175 Tkapp_CallDeallocArgs(objv, objStore, objc);
1176 return NULL;
1177}
Guido van Rossum212643f1998-04-29 16:22:14 +00001178
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001179/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001180
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001181static PyObject*
1182Tkapp_CallResult(TkappObject *self)
1183{
1184 PyObject *res = NULL;
1185 if(self->wantobjects) {
1186 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001187 /* Not sure whether the IncrRef is necessary, but something
1188 may overwrite the interpreter result while we are
1189 converting it. */
1190 Tcl_IncrRefCount(value);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001191 res = FromObj((PyObject*)self, value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001192 Tcl_DecrRefCount(value);
1193 } else {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001194 const char *s = Tcl_GetStringResult(self->interp);
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001195 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001196
Guido van Rossum990f5c62000-05-04 15:07:16 +00001197 /* If the result contains any bytes with the top bit set,
1198 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001199#ifdef Py_USING_UNICODE
Guido van Rossum990f5c62000-05-04 15:07:16 +00001200 while (*p != '\0') {
1201 if (*p & 0x80)
1202 break;
1203 p++;
1204 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001205
Guido van Rossum990f5c62000-05-04 15:07:16 +00001206 if (*p == '\0')
1207 res = PyString_FromStringAndSize(s, (int)(p-s));
1208 else {
1209 /* Convert UTF-8 to Unicode string */
1210 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +00001211 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
1212 if (res == NULL) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001213 PyErr_Clear();
1214 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +00001215 }
Guido van Rossum990f5c62000-05-04 15:07:16 +00001216 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001217#else
1218 p = strchr(p, '\0');
1219 res = PyString_FromStringAndSize(s, (int)(p-s));
1220#endif
Guido van Rossum990f5c62000-05-04 15:07:16 +00001221 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001222 return res;
1223}
Guido van Rossum632de272000-03-29 00:19:50 +00001224
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001225/* Tkapp_CallProc is the event procedure that is executed in the context of
1226 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1227 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001228
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001229static int
1230Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1231{
1232 Tcl_Obj *objStore[ARGSZ];
1233 Tcl_Obj **objv;
1234 int objc;
1235 int i;
1236 ENTER_PYTHON
1237 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1238 if (!objv) {
1239 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1240 *(e->res) = NULL;
1241 }
1242 LEAVE_PYTHON
1243 if (!objv)
1244 goto done;
1245 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1246 ENTER_PYTHON
1247 if (i == TCL_ERROR) {
1248 *(e->res) = NULL;
1249 *(e->exc_type) = NULL;
1250 *(e->exc_tb) = NULL;
1251 *(e->exc_value) = PyObject_CallFunction(
1252 Tkinter_TclError, "s",
1253 Tcl_GetStringResult(e->self->interp));
1254 }
1255 else {
1256 *(e->res) = Tkapp_CallResult(e->self);
1257 }
1258 LEAVE_PYTHON
1259 done:
1260 /* Wake up calling thread. */
1261 Tcl_MutexLock(&call_mutex);
1262 Tcl_ConditionNotify(&e->done);
1263 Tcl_MutexUnlock(&call_mutex);
1264 return 1;
1265}
1266
1267/* This is the main entry point for calling a Tcl command.
1268 It supports three cases, with regard to threading:
1269 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1270 the context of the calling thread.
1271 2. Tcl is threaded, caller of the command is in the interpreter thread:
1272 Execute the command in the calling thread. Since the Tcl lock will
1273 not be used, we can merge that with case 1.
1274 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1275 the interpreter thread. Allocation of Tcl objects needs to occur in the
1276 interpreter thread, so we ship the PyObject* args to the target thread,
1277 and perform processing there. */
1278
1279static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001280Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001281{
1282 Tcl_Obj *objStore[ARGSZ];
1283 Tcl_Obj **objv = NULL;
1284 int objc, i;
1285 PyObject *res = NULL;
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001286 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001287 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
1288 int flags = TCL_EVAL_DIRECT;
1289
Martin v. Löwisa9656492003-03-30 08:44:58 +00001290#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001291 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1292 /* We cannot call the command directly. Instead, we must
1293 marshal the parameters to the interpreter thread. */
1294 Tkapp_CallEvent *ev;
1295 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001296 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001297 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001298 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1299 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1300 ev->self = self;
1301 ev->args = args;
1302 ev->res = &res;
1303 ev->exc_type = &exc_type;
1304 ev->exc_value = &exc_value;
1305 ev->exc_tb = &exc_tb;
1306 ev->done = (Tcl_Condition)0;
1307
1308 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &call_mutex);
1309
1310 if (res == NULL) {
1311 if (exc_type)
1312 PyErr_Restore(exc_type, exc_value, exc_tb);
1313 else
1314 PyErr_SetObject(Tkinter_TclError, exc_value);
1315 }
1316 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001317 else
1318#endif
1319 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001320
1321 objv = Tkapp_CallArgs(args, objStore, &objc);
1322 if (!objv)
1323 return NULL;
1324
1325 ENTER_TCL
1326
1327 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1328
1329 ENTER_OVERLAP
1330
1331 if (i == TCL_ERROR)
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001332 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001333 else
1334 res = Tkapp_CallResult(self);
1335
1336 LEAVE_OVERLAP_TCL
1337
1338 Tkapp_CallDeallocArgs(objv, objStore, objc);
1339 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001340 return res;
1341}
1342
1343
1344static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001345Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001346{
Guido van Rossum212643f1998-04-29 16:22:14 +00001347 /* Could do the same here as for Tkapp_Call(), but this is not used
1348 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1349 way for the user to do what all its Global* variants do (save and
1350 reset the scope pointer, call the local version, restore the saved
1351 scope pointer). */
1352
Guido van Rossum62320c91998-06-15 04:36:09 +00001353 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001354 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001355
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001356 CHECK_TCL_APPARTMENT;
1357
Guido van Rossum62320c91998-06-15 04:36:09 +00001358 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001359 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001360 int err;
1361 ENTER_TCL
1362 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001363 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001364 if (err == TCL_ERROR)
1365 res = Tkinter_Error(self);
1366 else
1367 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001368 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001369 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001370 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001371
1372 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001373}
1374
1375static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001376Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001377{
Barry Warsawfa701a81997-01-16 00:15:11 +00001378 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001379 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001380 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001381
Guido van Rossum43713e52000-02-29 13:59:29 +00001382 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001383 return NULL;
1384
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001385 CHECK_TCL_APPARTMENT;
1386
Guido van Rossum00d93061998-05-28 23:06:38 +00001387 ENTER_TCL
1388 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001389 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001390 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001391 res = Tkinter_Error(self);
1392 else
1393 res = PyString_FromString(Tkapp_Result(self));
1394 LEAVE_OVERLAP_TCL
1395 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001396}
1397
1398static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001399Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001400{
Barry Warsawfa701a81997-01-16 00:15:11 +00001401 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001402 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001403 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001404
Guido van Rossum43713e52000-02-29 13:59:29 +00001405 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001406 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001407
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001408 CHECK_TCL_APPARTMENT;
1409
Guido van Rossum00d93061998-05-28 23:06:38 +00001410 ENTER_TCL
1411 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001412 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001413 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001414 res = Tkinter_Error(self);
1415 else
1416 res = PyString_FromString(Tkapp_Result(self));
1417 LEAVE_OVERLAP_TCL
1418 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001419}
1420
1421static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001422Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001423{
Barry Warsawfa701a81997-01-16 00:15:11 +00001424 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001425 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001426 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001427
Guido van Rossum43713e52000-02-29 13:59:29 +00001428 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001429 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001430
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001431 CHECK_TCL_APPARTMENT;
1432
Guido van Rossum00d93061998-05-28 23:06:38 +00001433 ENTER_TCL
1434 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001435 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001436 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001437 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001438
Guido van Rossum62320c91998-06-15 04:36:09 +00001439 else
1440 res = PyString_FromString(Tkapp_Result(self));
1441 LEAVE_OVERLAP_TCL
1442 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001443}
1444
1445static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001446Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001447{
Barry Warsawfa701a81997-01-16 00:15:11 +00001448 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001449 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001450 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001451
Guido van Rossum35d43371997-08-02 00:09:09 +00001452 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001453 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001454
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001455 CHECK_TCL_APPARTMENT;
1456
Guido van Rossum00d93061998-05-28 23:06:38 +00001457 ENTER_TCL
1458 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001459 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001460 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001461 res = Tkinter_Error(self);
1462 else
1463 res = PyString_FromString(Tkapp_Result(self));
1464 LEAVE_OVERLAP_TCL
1465 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001466}
1467
1468static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001469Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001470{
Barry Warsawfa701a81997-01-16 00:15:11 +00001471 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001472
Guido van Rossum43713e52000-02-29 13:59:29 +00001473 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001474 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001475 CHECK_TCL_APPARTMENT;
1476
Guido van Rossum00d93061998-05-28 23:06:38 +00001477 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001478 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001479 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001480
Barry Warsawfa701a81997-01-16 00:15:11 +00001481 Py_INCREF(Py_None);
1482 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001483}
1484
Barry Warsawfa701a81997-01-16 00:15:11 +00001485
1486
Guido van Rossum18468821994-06-20 07:49:28 +00001487/** Tcl Variable **/
1488
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001489TCL_DECLARE_MUTEX(var_mutex)
1490
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001491typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001492typedef struct VarEvent {
1493 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001494 PyObject *self;
1495 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001496 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001497 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001498 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001499 PyObject **exc_type;
1500 PyObject **exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001501 Tcl_Condition cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001502} VarEvent;
1503
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001504static int
1505varname_converter(PyObject *in, void *_out)
1506{
1507 char **out = (char**)_out;
1508 if (PyString_Check(in)) {
1509 *out = PyString_AsString(in);
1510 return 1;
1511 }
1512 if (PyTclObject_Check(in)) {
1513 *out = PyTclObject_TclString(in);
1514 return 1;
1515 }
1516 /* XXX: Should give diagnostics. */
1517 return 0;
1518}
1519
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001520void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001521var_perform(VarEvent *ev)
1522{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001523 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1524 if (!*(ev->res)) {
1525 PyObject *exc, *val, *tb;
1526 PyErr_Fetch(&exc, &val, &tb);
1527 PyErr_NormalizeException(&exc, &val, &tb);
1528 *(ev->exc_type) = exc;
1529 *(ev->exc_val) = val;
1530 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001531 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001532
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001533}
1534
1535static int
1536var_proc(VarEvent* ev, int flags)
1537{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001538 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001539 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001540 Tcl_MutexLock(&var_mutex);
1541 Tcl_ConditionNotify(&ev->cond);
1542 Tcl_MutexUnlock(&var_mutex);
1543 LEAVE_PYTHON
1544 return 1;
1545}
1546
1547static PyObject*
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001548var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001549{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001550 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisa9656492003-03-30 08:44:58 +00001551#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001552 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001553 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001554 VarEvent *ev;
1555 PyObject *res, *exc_type, *exc_val;
1556
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001557 /* The current thread is not the interpreter thread. Marshal
1558 the call to the interpreter thread, then wait for
1559 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001560 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001561 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001562
1563 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1564
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001565 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001566 ev->args = args;
1567 ev->flags = flags;
1568 ev->func = func;
1569 ev->res = &res;
1570 ev->exc_type = &exc_type;
1571 ev->exc_val = &exc_val;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001572 ev->cond = NULL;
1573 ev->ev.proc = (Tcl_EventProc*)var_proc;
1574 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001575 if (!res) {
1576 PyErr_SetObject(exc_type, exc_val);
1577 Py_DECREF(exc_type);
1578 Py_DECREF(exc_val);
1579 return NULL;
1580 }
1581 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001582 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001583#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001584 /* Tcl is not threaded, or this is the interpreter thread. */
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001585 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001586}
1587
Guido van Rossum18468821994-06-20 07:49:28 +00001588static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001589SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001590{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001591 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001592 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001593 PyObject *res = NULL;
1594 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001595
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001596 if (PyArg_ParseTuple(args, "O&O:setvar",
1597 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001598 /* XXX Acquire tcl lock??? */
1599 newval = AsObj(newValue);
1600 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001601 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001602 ENTER_TCL
1603 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1604 newval, flags);
1605 ENTER_OVERLAP
1606 if (!ok)
1607 Tkinter_Error(self);
1608 else {
1609 res = Py_None;
1610 Py_INCREF(res);
1611 }
1612 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001613 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001614 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001615 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001616 if (PyArg_ParseTuple(args, "ssO:setvar",
1617 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001618 /* XXX must hold tcl lock already??? */
1619 newval = AsObj(newValue);
1620 ENTER_TCL
1621 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1622 ENTER_OVERLAP
1623 if (!ok)
1624 Tkinter_Error(self);
1625 else {
1626 res = Py_None;
1627 Py_INCREF(res);
1628 }
1629 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001630 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001631 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001632 return NULL;
1633 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001634 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001635 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001636}
1637
1638static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001639Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001640{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001641 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001642}
1643
1644static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001645Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001646{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001647 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001648}
1649
Barry Warsawfa701a81997-01-16 00:15:11 +00001650
1651
Guido van Rossum18468821994-06-20 07:49:28 +00001652static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001653GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001654{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001655 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001656 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001657 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001658
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001659 if (!PyArg_ParseTuple(args, "O&|s:getvar",
1660 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001661 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001662
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001663 ENTER_TCL
1664 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1665 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001666 if (tres == NULL) {
1667 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1668 } else {
1669 if (((TkappObject*)self)->wantobjects) {
1670 res = FromObj(self, tres);
1671 }
1672 else {
1673 res = PyString_FromString(Tcl_GetString(tres));
1674 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001675 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001676 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001677 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001678}
1679
1680static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001681Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001682{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001683 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001684}
1685
1686static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001687Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001688{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001689 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001690}
1691
Barry Warsawfa701a81997-01-16 00:15:11 +00001692
1693
Guido van Rossum18468821994-06-20 07:49:28 +00001694static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001695UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001696{
Guido van Rossum35d43371997-08-02 00:09:09 +00001697 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001698 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001699 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001700
Guido van Rossum43713e52000-02-29 13:59:29 +00001701 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001702 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001703
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001704 ENTER_TCL
1705 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1706 ENTER_OVERLAP
1707 if (code == TCL_ERROR)
1708 res = Tkinter_Error(self);
1709 else {
1710 Py_INCREF(Py_None);
1711 res = Py_None;
1712 }
1713 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001714 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001715}
1716
1717static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001718Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001719{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001720 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001721}
1722
1723static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001724Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001725{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001726 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001727}
1728
Barry Warsawfa701a81997-01-16 00:15:11 +00001729
1730
Guido van Rossum18468821994-06-20 07:49:28 +00001731/** Tcl to Python **/
1732
1733static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001734Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001735{
Barry Warsawfa701a81997-01-16 00:15:11 +00001736 char *s;
1737 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001738
Martin v. Löwisffad6332002-11-26 09:28:05 +00001739 if (PyTuple_Size(args) == 1) {
1740 PyObject* o = PyTuple_GetItem(args, 0);
1741 if (PyInt_Check(o)) {
1742 Py_INCREF(o);
1743 return o;
1744 }
1745 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001746 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001747 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001748 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001749 return Tkinter_Error(self);
1750 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001751}
1752
1753static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001754Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001755{
Barry Warsawfa701a81997-01-16 00:15:11 +00001756 char *s;
1757 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001758
Martin v. Löwisffad6332002-11-26 09:28:05 +00001759 if (PyTuple_Size(args) == 1) {
1760 PyObject *o = PyTuple_GetItem(args, 0);
1761 if (PyFloat_Check(o)) {
1762 Py_INCREF(o);
1763 return o;
1764 }
1765 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001766 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001767 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001768 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001769 return Tkinter_Error(self);
1770 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001771}
1772
1773static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001774Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001775{
Barry Warsawfa701a81997-01-16 00:15:11 +00001776 char *s;
1777 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001778
Martin v. Löwisffad6332002-11-26 09:28:05 +00001779 if (PyTuple_Size(args) == 1) {
1780 PyObject *o = PyTuple_GetItem(args, 0);
1781 if (PyInt_Check(o)) {
1782 Py_INCREF(o);
1783 return o;
1784 }
1785 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001786 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001787 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001788 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1789 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001790 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001791}
1792
1793static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001794Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001795{
Barry Warsawfa701a81997-01-16 00:15:11 +00001796 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001797 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001798 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001799
Guido van Rossum43713e52000-02-29 13:59:29 +00001800 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001801 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001802
1803 CHECK_TCL_APPARTMENT;
1804
Guido van Rossum00d93061998-05-28 23:06:38 +00001805 ENTER_TCL
1806 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001807 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001808 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001809 res = Tkinter_Error(self);
1810 else
1811 res = Py_BuildValue("s", Tkapp_Result(self));
1812 LEAVE_OVERLAP_TCL
1813 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001814}
1815
1816static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001817Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001818{
Barry Warsawfa701a81997-01-16 00:15:11 +00001819 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001820 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001821 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001822 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001823
Guido van Rossum43713e52000-02-29 13:59:29 +00001824 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001825 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001826
1827 CHECK_TCL_APPARTMENT;
1828
Guido van Rossum00d93061998-05-28 23:06:38 +00001829 ENTER_TCL
1830 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001831 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001832 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001833 res = Tkinter_Error(self);
1834 else
1835 res = Py_BuildValue("l", v);
1836 LEAVE_OVERLAP_TCL
1837 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001838}
1839
1840static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001841Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001842{
Barry Warsawfa701a81997-01-16 00:15:11 +00001843 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001844 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001845 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001846 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001847
Guido van Rossum43713e52000-02-29 13:59:29 +00001848 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001849 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001850 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001851 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001852 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001853 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001854 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001855 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001856 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001857 res = Tkinter_Error(self);
1858 else
1859 res = Py_BuildValue("d", v);
1860 LEAVE_OVERLAP_TCL
1861 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001862}
1863
1864static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001865Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001866{
Barry Warsawfa701a81997-01-16 00:15:11 +00001867 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001868 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001869 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001870 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001871
Guido van Rossum43713e52000-02-29 13:59:29 +00001872 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001873 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001874 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001875 ENTER_TCL
1876 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001877 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001878 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001879 res = Tkinter_Error(self);
1880 else
1881 res = Py_BuildValue("i", v);
1882 LEAVE_OVERLAP_TCL
1883 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001884}
1885
Barry Warsawfa701a81997-01-16 00:15:11 +00001886
1887
Guido van Rossum18468821994-06-20 07:49:28 +00001888static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001889Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001890{
Barry Warsawfa701a81997-01-16 00:15:11 +00001891 char *list;
1892 int argc;
1893 char **argv;
1894 PyObject *v;
1895 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001896
Martin v. Löwisffad6332002-11-26 09:28:05 +00001897 if (PyTuple_Size(args) == 1) {
1898 v = PyTuple_GetItem(args, 0);
1899 if (PyTuple_Check(v)) {
1900 Py_INCREF(v);
1901 return v;
1902 }
1903 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001904 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001905 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001906
Neal Norwitzd1c55102003-05-29 00:17:03 +00001907 if (Tcl_SplitList(Tkapp_Interp(self), list,
1908 &argc, &argv) == TCL_ERROR) {
1909 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001910 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001911 }
Guido van Rossum18468821994-06-20 07:49:28 +00001912
Barry Warsawfa701a81997-01-16 00:15:11 +00001913 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001914 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001915
Barry Warsawfa701a81997-01-16 00:15:11 +00001916 for (i = 0; i < argc; i++) {
1917 PyObject *s = PyString_FromString(argv[i]);
1918 if (!s || PyTuple_SetItem(v, i, s)) {
1919 Py_DECREF(v);
1920 v = NULL;
1921 goto finally;
1922 }
1923 }
Guido van Rossum18468821994-06-20 07:49:28 +00001924
Barry Warsawfa701a81997-01-16 00:15:11 +00001925 finally:
1926 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001927 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001928 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001929}
1930
1931static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001932Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001933{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001934 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001935 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001936
Martin v. Löwisffad6332002-11-26 09:28:05 +00001937 if (PyTuple_Size(args) == 1) {
1938 PyObject* o = PyTuple_GetItem(args, 0);
1939 if (PyTuple_Check(o)) {
1940 o = SplitObj(o);
1941 return o;
1942 }
1943 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001944 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001945 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00001946 v = Split(list);
1947 PyMem_Free(list);
1948 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001949}
1950
1951static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001952Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001953{
Barry Warsawfa701a81997-01-16 00:15:11 +00001954 char *s = Merge(args);
1955 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001956
Barry Warsawfa701a81997-01-16 00:15:11 +00001957 if (s) {
1958 res = PyString_FromString(s);
1959 ckfree(s);
1960 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001961
1962 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001963}
1964
Barry Warsawfa701a81997-01-16 00:15:11 +00001965
1966
Guido van Rossum18468821994-06-20 07:49:28 +00001967/** Tcl Command **/
1968
Guido van Rossum00d93061998-05-28 23:06:38 +00001969/* Client data struct */
1970typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001971 PyObject *self;
1972 PyObject *func;
1973} PythonCmd_ClientData;
1974
1975static int
Fred Drake509d79a2000-07-08 04:04:38 +00001976PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001977{
1978 errorInCmd = 1;
1979 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1980 LEAVE_PYTHON
1981 return TCL_ERROR;
1982}
1983
Guido van Rossum18468821994-06-20 07:49:28 +00001984/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001985 * function or method.
1986 */
Guido van Rossum18468821994-06-20 07:49:28 +00001987static int
Fred Drake509d79a2000-07-08 04:04:38 +00001988PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001989{
Guido van Rossum00d93061998-05-28 23:06:38 +00001990 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001991 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001992 int i, rv;
1993 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001994
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001995 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001996
Barry Warsawfa701a81997-01-16 00:15:11 +00001997 /* TBD: no error checking here since we know, via the
1998 * Tkapp_CreateCommand() that the client data is a two-tuple
1999 */
Guido van Rossum00d93061998-05-28 23:06:38 +00002000 self = data->self;
2001 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00002002
Barry Warsawfa701a81997-01-16 00:15:11 +00002003 /* Create argument list (argv1, ..., argvN) */
2004 if (!(arg = PyTuple_New(argc - 1)))
2005 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00002006
Barry Warsawfa701a81997-01-16 00:15:11 +00002007 for (i = 0; i < (argc - 1); i++) {
2008 PyObject *s = PyString_FromString(argv[i + 1]);
2009 if (!s || PyTuple_SetItem(arg, i, s)) {
2010 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00002011 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00002012 }
2013 }
2014 res = PyEval_CallObject(func, arg);
2015 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00002016
Barry Warsawfa701a81997-01-16 00:15:11 +00002017 if (res == NULL)
2018 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00002019
Barry Warsawfa701a81997-01-16 00:15:11 +00002020 if (!(tmp = PyList_New(0))) {
2021 Py_DECREF(res);
2022 return PythonCmd_Error(interp);
2023 }
2024
Guido van Rossum2834b972000-10-06 16:58:26 +00002025 s = AsString(res, tmp);
2026 if (s == NULL) {
2027 rv = PythonCmd_Error(interp);
2028 }
2029 else {
2030 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
2031 rv = TCL_OK;
2032 }
2033
Barry Warsawfa701a81997-01-16 00:15:11 +00002034 Py_DECREF(res);
2035 Py_DECREF(tmp);
2036
Guido van Rossum00d93061998-05-28 23:06:38 +00002037 LEAVE_PYTHON
2038
Guido van Rossum2834b972000-10-06 16:58:26 +00002039 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002040}
2041
2042static void
Fred Drake509d79a2000-07-08 04:04:38 +00002043PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002044{
Guido van Rossum00d93061998-05-28 23:06:38 +00002045 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2046
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002047 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002048 Py_XDECREF(data->self);
2049 Py_XDECREF(data->func);
2050 PyMem_DEL(data);
2051 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002052}
2053
Barry Warsawfa701a81997-01-16 00:15:11 +00002054
2055
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002056
2057TCL_DECLARE_MUTEX(command_mutex)
2058
2059typedef struct CommandEvent{
2060 Tcl_Event ev;
2061 Tcl_Interp* interp;
2062 char *name;
2063 int create;
2064 int *status;
2065 ClientData *data;
2066 Tcl_Condition done;
2067} CommandEvent;
2068
2069static int
2070Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002071{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002072 if (ev->create)
2073 *ev->status = Tcl_CreateCommand(
2074 ev->interp, ev->name, PythonCmd,
2075 ev->data, PythonCmdDelete) == NULL;
2076 else
2077 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2078 Tcl_MutexLock(&command_mutex);
2079 Tcl_ConditionNotify(&ev->done);
2080 Tcl_MutexUnlock(&command_mutex);
2081 return 1;
2082}
2083
2084static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002085Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002086{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002087 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002088 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002089 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002090 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002091 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002092
Guido van Rossum43713e52000-02-29 13:59:29 +00002093 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002094 return NULL;
2095 if (!PyCallable_Check(func)) {
2096 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002097 return NULL;
2098 }
Guido van Rossum18468821994-06-20 07:49:28 +00002099
Martin v. Löwisa9656492003-03-30 08:44:58 +00002100#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002101 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002102 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002103 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002104#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002105
Guido van Rossum00d93061998-05-28 23:06:38 +00002106 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002107 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002108 return PyErr_NoMemory();
Neal Norwitzce5b3c32006-07-16 02:02:57 +00002109 Py_INCREF(self);
2110 Py_INCREF(func);
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002111 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002112 data->func = func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002113
2114 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2115 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2116 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2117 ev->interp = self->interp;
2118 ev->create = 1;
2119 ev->name = cmdName;
2120 ev->data = (ClientData)data;
2121 ev->status = &err;
2122 ev->done = NULL;
2123 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
2124 }
2125 else {
2126 ENTER_TCL
2127 err = Tcl_CreateCommand(
2128 Tkapp_Interp(self), cmdName, PythonCmd,
2129 (ClientData)data, PythonCmdDelete) == NULL;
2130 LEAVE_TCL
2131 }
2132 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002133 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002134 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002135 return NULL;
2136 }
Guido van Rossum18468821994-06-20 07:49:28 +00002137
Barry Warsawfa701a81997-01-16 00:15:11 +00002138 Py_INCREF(Py_None);
2139 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002140}
2141
Barry Warsawfa701a81997-01-16 00:15:11 +00002142
2143
Guido van Rossum18468821994-06-20 07:49:28 +00002144static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002145Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002146{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002147 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002148 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002149 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002150
Guido van Rossum43713e52000-02-29 13:59:29 +00002151 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002152 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002153 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2154 CommandEvent *ev;
2155 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2156 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2157 ev->interp = self->interp;
2158 ev->create = 0;
2159 ev->name = cmdName;
2160 ev->status = &err;
2161 ev->done = NULL;
2162 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done,
2163 &command_mutex);
2164 }
2165 else {
2166 ENTER_TCL
2167 err = Tcl_DeleteCommand(self->interp, cmdName);
2168 LEAVE_TCL
2169 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002170 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002171 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2172 return NULL;
2173 }
2174 Py_INCREF(Py_None);
2175 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002176}
2177
Barry Warsawfa701a81997-01-16 00:15:11 +00002178
2179
Guido van Rossum00d93061998-05-28 23:06:38 +00002180#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002181/** File Handler **/
2182
Guido van Rossum00d93061998-05-28 23:06:38 +00002183typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002184 PyObject *func;
2185 PyObject *file;
2186 int id;
2187 struct _fhcdata *next;
2188} FileHandler_ClientData;
2189
2190static FileHandler_ClientData *HeadFHCD;
2191
2192static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002193NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002194{
2195 FileHandler_ClientData *p;
2196 p = PyMem_NEW(FileHandler_ClientData, 1);
2197 if (p != NULL) {
2198 Py_XINCREF(func);
2199 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002200 p->func = func;
2201 p->file = file;
2202 p->id = id;
2203 p->next = HeadFHCD;
2204 HeadFHCD = p;
2205 }
2206 return p;
2207}
2208
2209static void
Fred Drake509d79a2000-07-08 04:04:38 +00002210DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002211{
2212 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002213
2214 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002215 while ((p = *pp) != NULL) {
2216 if (p->id == id) {
2217 *pp = p->next;
2218 Py_XDECREF(p->func);
2219 Py_XDECREF(p->file);
2220 PyMem_DEL(p);
2221 }
2222 else
2223 pp = &p->next;
2224 }
2225}
2226
Guido van Rossuma597dde1995-01-10 20:56:29 +00002227static void
Fred Drake509d79a2000-07-08 04:04:38 +00002228FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002229{
Guido van Rossum00d93061998-05-28 23:06:38 +00002230 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002231 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002232
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002233 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002234 func = data->func;
2235 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002236
Barry Warsawfa701a81997-01-16 00:15:11 +00002237 arg = Py_BuildValue("(Oi)", file, (long) mask);
2238 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002239 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002240
2241 if (res == NULL) {
2242 errorInCmd = 1;
2243 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2244 }
2245 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002246 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002247}
2248
Guido van Rossum18468821994-06-20 07:49:28 +00002249static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002250Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2251 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002252{
Guido van Rossum00d93061998-05-28 23:06:38 +00002253 FileHandler_ClientData *data;
2254 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002255 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002256
Guido van Rossum2834b972000-10-06 16:58:26 +00002257 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2258 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002259 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002260
Martin v. Löwisa9656492003-03-30 08:44:58 +00002261#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002262 if (!self && !tcl_lock) {
2263 /* We don't have the Tcl lock since Tcl is threaded. */
2264 PyErr_SetString(PyExc_RuntimeError,
2265 "_tkinter.createfilehandler not supported "
2266 "for threaded Tcl");
2267 return NULL;
2268 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002269#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002270
2271 if (self) {
2272 CHECK_TCL_APPARTMENT;
2273 }
2274
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002275 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002276 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002277 return NULL;
2278 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002279 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002280 return NULL;
2281 }
2282
Guido van Rossuma80649b2000-03-28 20:07:05 +00002283 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002284 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002285 return NULL;
2286
Barry Warsawfa701a81997-01-16 00:15:11 +00002287 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002288 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002289 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002290 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002291 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002292 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002293}
2294
2295static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002296Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002297{
Barry Warsawfa701a81997-01-16 00:15:11 +00002298 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002299 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002300
Guido van Rossum43713e52000-02-29 13:59:29 +00002301 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002302 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002303
Martin v. Löwisa9656492003-03-30 08:44:58 +00002304#ifdef WITH_THREAD
Neal Norwitz12e22172003-03-03 21:16:39 +00002305 if (!self && !tcl_lock) {
2306 /* We don't have the Tcl lock since Tcl is threaded. */
2307 PyErr_SetString(PyExc_RuntimeError,
2308 "_tkinter.deletefilehandler not supported "
2309 "for threaded Tcl");
2310 return NULL;
2311 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002312#endif
Neal Norwitz12e22172003-03-03 21:16:39 +00002313
2314 if (self) {
2315 CHECK_TCL_APPARTMENT;
2316 }
2317
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002318 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002319 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002320 return NULL;
2321
Guido van Rossuma80649b2000-03-28 20:07:05 +00002322 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002323
Barry Warsawfa701a81997-01-16 00:15:11 +00002324 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002325 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002326 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002327 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002328 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002329 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002330}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002331#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002332
Barry Warsawfa701a81997-01-16 00:15:11 +00002333
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002334/**** Tktt Object (timer token) ****/
2335
Jeremy Hylton938ace62002-07-17 16:30:39 +00002336static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002337
Guido van Rossum00d93061998-05-28 23:06:38 +00002338typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002339 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002340 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002341 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002342} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002343
2344static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002345Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002346{
Barry Warsawfa701a81997-01-16 00:15:11 +00002347 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002348 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002349
Guido van Rossum43713e52000-02-29 13:59:29 +00002350 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002351 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002352 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002353 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002354 v->token = NULL;
2355 }
2356 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002357 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002358 Py_DECREF(func);
2359 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002360 }
2361 Py_INCREF(Py_None);
2362 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002363}
2364
2365static PyMethodDef Tktt_methods[] =
2366{
Neal Norwitzb0493252002-03-31 14:44:22 +00002367 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002368 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002369};
2370
2371static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002372Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002373{
Barry Warsawfa701a81997-01-16 00:15:11 +00002374 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002375
Guido van Rossumb18618d2000-05-03 23:44:39 +00002376 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002377 if (v == NULL)
2378 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002379
Guido van Rossum00d93061998-05-28 23:06:38 +00002380 Py_INCREF(func);
2381 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002382 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002383
2384 /* Extra reference, deleted when called or when handler is deleted */
2385 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002386 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002387}
2388
2389static void
Fred Drake509d79a2000-07-08 04:04:38 +00002390Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002391{
Guido van Rossum00d93061998-05-28 23:06:38 +00002392 TkttObject *v = (TkttObject *)self;
2393 PyObject *func = v->func;
2394
2395 Py_XDECREF(func);
2396
Guido van Rossumb18618d2000-05-03 23:44:39 +00002397 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002398}
2399
Guido van Rossum597ac201998-05-12 14:36:19 +00002400static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002401Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002402{
Barry Warsawfa701a81997-01-16 00:15:11 +00002403 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002404 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002405
Tim Peters885d4572001-11-28 20:27:42 +00002406 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002407 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00002408 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002409}
2410
2411static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002412Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002413{
Barry Warsawfa701a81997-01-16 00:15:11 +00002414 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002415}
2416
2417static PyTypeObject Tktt_Type =
2418{
Guido van Rossum35d43371997-08-02 00:09:09 +00002419 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002420 0, /*ob_size */
2421 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002422 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002423 0, /*tp_itemsize */
2424 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002425 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00002426 Tktt_GetAttr, /*tp_getattr */
2427 0, /*tp_setattr */
2428 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00002429 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002430 0, /*tp_as_number */
2431 0, /*tp_as_sequence */
2432 0, /*tp_as_mapping */
2433 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002434};
2435
Barry Warsawfa701a81997-01-16 00:15:11 +00002436
2437
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002438/** Timer Handler **/
2439
2440static void
Fred Drake509d79a2000-07-08 04:04:38 +00002441TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002442{
Guido van Rossum00d93061998-05-28 23:06:38 +00002443 TkttObject *v = (TkttObject *)clientData;
2444 PyObject *func = v->func;
2445 PyObject *res;
2446
2447 if (func == NULL)
2448 return;
2449
2450 v->func = NULL;
2451
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002452 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002453
2454 res = PyEval_CallObject(func, NULL);
2455 Py_DECREF(func);
2456 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002457
Barry Warsawfa701a81997-01-16 00:15:11 +00002458 if (res == NULL) {
2459 errorInCmd = 1;
2460 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2461 }
2462 else
2463 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002464
2465 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002466}
2467
2468static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002469Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002470{
Barry Warsawfa701a81997-01-16 00:15:11 +00002471 int milliseconds;
2472 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002473 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002474
Guido van Rossum2834b972000-10-06 16:58:26 +00002475 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2476 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002477 return NULL;
2478 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002479 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002480 return NULL;
2481 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002482
Martin v. Löwisa9656492003-03-30 08:44:58 +00002483#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002484 if (!self && !tcl_lock) {
2485 /* We don't have the Tcl lock since Tcl is threaded. */
2486 PyErr_SetString(PyExc_RuntimeError,
2487 "_tkinter.createtimerhandler not supported "
2488 "for threaded Tcl");
2489 return NULL;
2490 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002491#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002492
2493 if (self) {
2494 CHECK_TCL_APPARTMENT;
2495 }
2496
Guido van Rossum00d93061998-05-28 23:06:38 +00002497 v = Tktt_New(func);
Neal Norwitz5f17d9a2006-08-12 02:33:36 +00002498 if (v) {
2499 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2500 (ClientData)v);
2501 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002502
Guido van Rossum00d93061998-05-28 23:06:38 +00002503 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002504}
2505
Barry Warsawfa701a81997-01-16 00:15:11 +00002506
Guido van Rossum18468821994-06-20 07:49:28 +00002507/** Event Loop **/
2508
Guido van Rossum18468821994-06-20 07:49:28 +00002509static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002510Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002511{
Barry Warsawfa701a81997-01-16 00:15:11 +00002512 int threshold = 0;
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002513 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002514#ifdef WITH_THREAD
2515 PyThreadState *tstate = PyThreadState_Get();
2516#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002517
Guido van Rossum43713e52000-02-29 13:59:29 +00002518 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002519 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002520
Martin v. Löwisa9656492003-03-30 08:44:58 +00002521#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002522 if (!self && !tcl_lock) {
2523 /* We don't have the Tcl lock since Tcl is threaded. */
2524 PyErr_SetString(PyExc_RuntimeError,
2525 "_tkinter.mainloop not supported "
2526 "for threaded Tcl");
2527 return NULL;
2528 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002529#endif
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002530
2531 if (self) {
2532 CHECK_TCL_APPARTMENT;
2533 self->dispatching = 1;
2534 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002535
Barry Warsawfa701a81997-01-16 00:15:11 +00002536 quitMainLoop = 0;
2537 while (Tk_GetNumMainWindows() > threshold &&
2538 !quitMainLoop &&
2539 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002540 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002541 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002542
2543#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002544 if (self && self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002545 /* Allow other Python threads to run. */
2546 ENTER_TCL
2547 result = Tcl_DoOneEvent(0);
2548 LEAVE_TCL
2549 }
2550 else {
2551 Py_BEGIN_ALLOW_THREADS
2552 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2553 tcl_tstate = tstate;
2554 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2555 tcl_tstate = NULL;
2556 if(tcl_lock)PyThread_release_lock(tcl_lock);
2557 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002558 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002559 Py_END_ALLOW_THREADS
2560 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002561#else
2562 result = Tcl_DoOneEvent(0);
2563#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002564
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002565 if (PyErr_CheckSignals() != 0) {
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002566 if (self)
2567 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002568 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002569 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002570 if (result < 0)
2571 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002572 }
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002573 if (self)
2574 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002575 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002576
Barry Warsawfa701a81997-01-16 00:15:11 +00002577 if (errorInCmd) {
2578 errorInCmd = 0;
2579 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2580 excInCmd = valInCmd = trbInCmd = NULL;
2581 return NULL;
2582 }
2583 Py_INCREF(Py_None);
2584 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002585}
2586
2587static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002588Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002589{
Guido van Rossum35d43371997-08-02 00:09:09 +00002590 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002591 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002592
Guido van Rossum43713e52000-02-29 13:59:29 +00002593 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002594 return NULL;
2595
Guido van Rossum00d93061998-05-28 23:06:38 +00002596 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002597 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002598 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002599 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002600}
2601
2602static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002603Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002604{
2605
Guido van Rossum43713e52000-02-29 13:59:29 +00002606 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002607 return NULL;
2608
2609 quitMainLoop = 1;
2610 Py_INCREF(Py_None);
2611 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002612}
2613
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002614static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002615Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002616{
2617
Guido van Rossum43713e52000-02-29 13:59:29 +00002618 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002619 return NULL;
2620
2621 return PyInt_FromLong((long)Tkapp_Interp(self));
2622}
2623
David Aschere2b4b322004-02-18 05:59:53 +00002624static PyObject *
2625Tkapp_TkInit(PyObject *self, PyObject *args)
2626{
Martin v. Löwis86725192006-05-01 06:28:01 +00002627 static int has_failed;
David Aschere2b4b322004-02-18 05:59:53 +00002628 Tcl_Interp *interp = Tkapp_Interp(self);
Neal Norwitz44dbae82004-02-19 02:44:22 +00002629 Tk_Window main_window;
David Aschere2b4b322004-02-18 05:59:53 +00002630 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002631 int err;
Neal Norwitz44dbae82004-02-19 02:44:22 +00002632 main_window = Tk_MainWindow(interp);
David Aschere2b4b322004-02-18 05:59:53 +00002633
Martin v. Löwis86725192006-05-01 06:28:01 +00002634 /* In all current versions of Tk (including 8.4.13), Tk_Init
2635 deadlocks on the second call when the first call failed.
2636 To avoid the deadlock, we just refuse the second call through
2637 a static variable. */
2638 if (has_failed) {
2639 PyErr_SetString(Tkinter_TclError,
2640 "Calling Tk_Init again after a previous call failed might deadlock");
2641 return NULL;
2642 }
2643
David Aschere2b4b322004-02-18 05:59:53 +00002644 /* We want to guard against calling Tk_Init() multiple times */
2645 CHECK_TCL_APPARTMENT;
2646 ENTER_TCL
2647 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2648 ENTER_OVERLAP
2649 if (err == TCL_ERROR) {
Martin v. Löwis86725192006-05-01 06:28:01 +00002650 /* This sets an exception, but we cannot return right
2651 away because we need to exit the overlap first. */
2652 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002653 } else {
2654 _tk_exists = Tkapp_Result(self);
2655 }
2656 LEAVE_OVERLAP_TCL
2657 if (err == TCL_ERROR) {
2658 return NULL;
2659 }
2660 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2661 if (Tk_Init(interp) == TCL_ERROR) {
2662 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
Martin v. Löwis86725192006-05-01 06:28:01 +00002663 has_failed = 1;
David Aschere2b4b322004-02-18 05:59:53 +00002664 return NULL;
2665 }
2666 }
2667 Py_INCREF(Py_None);
2668 return Py_None;
2669}
Barry Warsawfa701a81997-01-16 00:15:11 +00002670
Martin v. Löwisffad6332002-11-26 09:28:05 +00002671static PyObject *
2672Tkapp_WantObjects(PyObject *self, PyObject *args)
2673{
2674
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002675 int wantobjects = -1;
2676 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002677 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002678 if (wantobjects == -1)
2679 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002680 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002681
2682 Py_INCREF(Py_None);
2683 return Py_None;
2684}
2685
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002686static PyObject *
2687Tkapp_WillDispatch(PyObject *self, PyObject *args)
2688{
2689
2690 ((TkappObject*)self)->dispatching = 1;
2691
2692 Py_INCREF(Py_None);
2693 return Py_None;
2694}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002695
Barry Warsawfa701a81997-01-16 00:15:11 +00002696
Guido van Rossum18468821994-06-20 07:49:28 +00002697/**** Tkapp Method List ****/
2698
2699static PyMethodDef Tkapp_methods[] =
2700{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002701 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002702 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002703 {"call", Tkapp_Call, METH_OLDARGS},
2704 {"globalcall", Tkapp_GlobalCall, METH_OLDARGS},
2705 {"eval", Tkapp_Eval, METH_VARARGS},
2706 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2707 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2708 {"record", Tkapp_Record, METH_VARARGS},
2709 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2710 {"setvar", Tkapp_SetVar, METH_VARARGS},
2711 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2712 {"getvar", Tkapp_GetVar, METH_VARARGS},
2713 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2714 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2715 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2716 {"getint", Tkapp_GetInt, METH_VARARGS},
2717 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2718 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2719 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2720 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2721 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2722 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2723 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2724 {"split", Tkapp_Split, METH_VARARGS},
2725 {"merge", Tkapp_Merge, METH_OLDARGS},
2726 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2727 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002728#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002729 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2730 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002731#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002732 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2733 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2734 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2735 {"quit", Tkapp_Quit, METH_VARARGS},
2736 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002737 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002738 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002739};
2740
Barry Warsawfa701a81997-01-16 00:15:11 +00002741
2742
Guido van Rossum18468821994-06-20 07:49:28 +00002743/**** Tkapp Type Methods ****/
2744
2745static void
Fred Drake509d79a2000-07-08 04:04:38 +00002746Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002747{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002748 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002749 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002750 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002751 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002752 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002753 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002754}
2755
2756static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002757Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002758{
Guido van Rossum35d43371997-08-02 00:09:09 +00002759 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002760}
2761
2762static PyTypeObject Tkapp_Type =
2763{
Guido van Rossum35d43371997-08-02 00:09:09 +00002764 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002765 0, /*ob_size */
2766 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002767 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002768 0, /*tp_itemsize */
2769 Tkapp_Dealloc, /*tp_dealloc */
2770 0, /*tp_print */
2771 Tkapp_GetAttr, /*tp_getattr */
2772 0, /*tp_setattr */
2773 0, /*tp_compare */
2774 0, /*tp_repr */
2775 0, /*tp_as_number */
2776 0, /*tp_as_sequence */
2777 0, /*tp_as_mapping */
2778 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002779};
2780
Barry Warsawfa701a81997-01-16 00:15:11 +00002781
2782
Guido van Rossum18468821994-06-20 07:49:28 +00002783/**** Tkinter Module ****/
2784
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002785typedef struct {
2786 PyObject* tuple;
2787 int size; /* current size */
2788 int maxsize; /* allocated size */
2789} FlattenContext;
2790
2791static int
2792_bump(FlattenContext* context, int size)
2793{
Guido van Rossum2834b972000-10-06 16:58:26 +00002794 /* expand tuple to hold (at least) size new items.
2795 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002796
2797 int maxsize = context->maxsize * 2;
2798
2799 if (maxsize < context->size + size)
2800 maxsize = context->size + size;
2801
2802 context->maxsize = maxsize;
2803
Tim Peters4324aa32001-05-28 22:30:08 +00002804 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002805}
2806
2807static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002808_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002809{
2810 /* add tuple or list to argument tuple (recursively) */
2811
2812 int i, size;
2813
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002814 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002815 PyErr_SetString(PyExc_ValueError,
2816 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002817 return 0;
2818 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002819 size = PyList_GET_SIZE(item);
2820 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002821 if (context->size + size > context->maxsize &&
2822 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002823 return 0;
2824 /* copy items to output tuple */
2825 for (i = 0; i < size; i++) {
2826 PyObject *o = PyList_GET_ITEM(item, i);
2827 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002828 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002829 return 0;
2830 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002831 if (context->size + 1 > context->maxsize &&
2832 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002833 return 0;
2834 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002835 PyTuple_SET_ITEM(context->tuple,
2836 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002837 }
2838 }
2839 } else if (PyTuple_Check(item)) {
2840 /* same, for tuples */
2841 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002842 if (context->size + size > context->maxsize &&
2843 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002844 return 0;
2845 for (i = 0; i < size; i++) {
2846 PyObject *o = PyTuple_GET_ITEM(item, i);
2847 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002848 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002849 return 0;
2850 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002851 if (context->size + 1 > context->maxsize &&
2852 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002853 return 0;
2854 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002855 PyTuple_SET_ITEM(context->tuple,
2856 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002857 }
2858 }
2859 } else {
2860 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2861 return 0;
2862 }
2863 return 1;
2864}
2865
2866static PyObject *
2867Tkinter_Flatten(PyObject* self, PyObject* args)
2868{
2869 FlattenContext context;
2870 PyObject* item;
2871
2872 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2873 return NULL;
2874
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002875 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002876 if (context.maxsize <= 0)
2877 return PyTuple_New(0);
2878
2879 context.tuple = PyTuple_New(context.maxsize);
2880 if (!context.tuple)
2881 return NULL;
2882
2883 context.size = 0;
2884
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002885 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002886 return NULL;
2887
Tim Peters4324aa32001-05-28 22:30:08 +00002888 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002889 return NULL;
2890
2891 return context.tuple;
2892}
2893
Guido van Rossum18468821994-06-20 07:49:28 +00002894static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002895Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002896{
Barry Warsawfa701a81997-01-16 00:15:11 +00002897 char *screenName = NULL;
2898 char *baseName = NULL;
2899 char *className = NULL;
2900 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002901 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002902 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002903 int sync = 0; /* pass -sync to wish */
2904 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002905
Guido van Rossum35d43371997-08-02 00:09:09 +00002906 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002907 if (baseName != NULL)
2908 baseName++;
2909 else
2910 baseName = Py_GetProgramName();
2911 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002912
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002913 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002914 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002915 &interactive, &wantobjects, &wantTk,
2916 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00002917 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002918
Barry Warsawfa701a81997-01-16 00:15:11 +00002919 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002920 interactive, wantobjects, wantTk,
2921 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002922}
2923
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002924static PyObject *
2925Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2926{
2927 int new_val;
2928 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2929 return NULL;
2930 if (new_val < 0) {
2931 PyErr_SetString(PyExc_ValueError,
2932 "busywaitinterval must be >= 0");
2933 return NULL;
2934 }
2935 Tkinter_busywaitinterval = new_val;
2936 Py_INCREF(Py_None);
2937 return Py_None;
2938}
2939
2940static char setbusywaitinterval_doc[] =
2941"setbusywaitinterval(n) -> None\n\
2942\n\
2943Set the busy-wait interval in milliseconds between successive\n\
2944calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2945It should be set to a divisor of the maximum time between\n\
2946frames in an animation.";
2947
2948static PyObject *
2949Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2950{
2951 return PyInt_FromLong(Tkinter_busywaitinterval);
2952}
2953
2954static char getbusywaitinterval_doc[] =
2955"getbusywaitinterval() -> int\n\
2956\n\
2957Return the current busy-wait interval between successive\n\
2958calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2959
Guido van Rossum18468821994-06-20 07:49:28 +00002960static PyMethodDef moduleMethods[] =
2961{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002962 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2963 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002964#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002965 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2966 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002967#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002968 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2969 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2970 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2971 {"quit", Tkapp_Quit, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002972 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2973 setbusywaitinterval_doc},
2974 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2975 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00002976 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002977};
2978
Guido van Rossum7bf15641998-05-22 18:28:17 +00002979#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002980
2981static int stdin_ready = 0;
2982
Guido van Rossumad4db171998-06-13 13:56:28 +00002983#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002984static void
Fred Drake509d79a2000-07-08 04:04:38 +00002985MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002986{
2987 stdin_ready = 1;
2988}
Guido van Rossumad4db171998-06-13 13:56:28 +00002989#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002990
Martin v. Löwisa9656492003-03-30 08:44:58 +00002991#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002992static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002993#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002994
Guido van Rossum18468821994-06-20 07:49:28 +00002995static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002996EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002997{
Guido van Rossumad4db171998-06-13 13:56:28 +00002998#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002999 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00003000#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003001#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003002 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003003#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003004 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00003005 errorInCmd = 0;
3006#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00003007 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003008 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00003009#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003010 while (!errorInCmd && !stdin_ready) {
3011 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00003012#ifdef MS_WINDOWS
3013 if (_kbhit()) {
3014 stdin_ready = 1;
3015 break;
3016 }
3017#endif
3018#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00003019 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003020 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00003021 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003022
Guido van Rossum00d93061998-05-28 23:06:38 +00003023 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003024
3025 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003026 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00003027 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003028 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00003029 Py_END_ALLOW_THREADS
3030#else
3031 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003032#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003033
3034 if (result < 0)
3035 break;
3036 }
Guido van Rossumad4db171998-06-13 13:56:28 +00003037#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00003038 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00003039#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003040 if (errorInCmd) {
3041 errorInCmd = 0;
3042 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3043 excInCmd = valInCmd = trbInCmd = NULL;
3044 PyErr_Print();
3045 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003046#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003047 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003048#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003049 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00003050}
Guido van Rossum18468821994-06-20 07:49:28 +00003051
Guido van Rossum00d93061998-05-28 23:06:38 +00003052#endif
3053
Guido van Rossum7bf15641998-05-22 18:28:17 +00003054static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003055EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003056{
Guido van Rossum00d93061998-05-28 23:06:38 +00003057#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003058 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003059#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003060 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003061#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003062 PyOS_InputHook = EventHook;
3063 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003064#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003065}
3066
3067static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003068DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003069{
Guido van Rossum00d93061998-05-28 23:06:38 +00003070#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003071 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3072 PyOS_InputHook = NULL;
3073 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003074#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003075}
3076
Barry Warsawfa701a81997-01-16 00:15:11 +00003077
3078/* all errors will be checked in one fell swoop in init_tkinter() */
3079static void
Fred Drake509d79a2000-07-08 04:04:38 +00003080ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003081{
3082 PyObject *v = PyInt_FromLong(val);
3083 if (v) {
3084 PyDict_SetItemString(d, name, v);
3085 Py_DECREF(v);
3086 }
3087}
3088static void
Fred Drake509d79a2000-07-08 04:04:38 +00003089ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003090{
3091 PyObject *v = PyString_FromString(val);
3092 if (v) {
3093 PyDict_SetItemString(d, name, v);
3094 Py_DECREF(v);
3095 }
3096}
3097
3098
Mark Hammond62b1ab12002-07-23 06:31:15 +00003099PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003100init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003101{
Barry Warsawfa701a81997-01-16 00:15:11 +00003102 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00003103
Barry Warsawfa701a81997-01-16 00:15:11 +00003104 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00003105
3106#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003107 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003108#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003109
Barry Warsawfa701a81997-01-16 00:15:11 +00003110 m = Py_InitModule("_tkinter", moduleMethods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003111 if (m == NULL)
3112 return;
Guido van Rossum18468821994-06-20 07:49:28 +00003113
Barry Warsawfa701a81997-01-16 00:15:11 +00003114 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003115 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003116 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003117
Guido van Rossum35d43371997-08-02 00:09:09 +00003118 ins_long(d, "READABLE", TCL_READABLE);
3119 ins_long(d, "WRITABLE", TCL_WRITABLE);
3120 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3121 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3122 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3123 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3124 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3125 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3126 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003127 ins_string(d, "TK_VERSION", TK_VERSION);
3128 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003129
Guido van Rossum83551bf1997-09-13 00:44:23 +00003130 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003131
3132 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003133 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3134
Martin v. Löwisffad6332002-11-26 09:28:05 +00003135 PyTclObject_Type.ob_type = &PyType_Type;
3136 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003137
3138#ifdef TK_AQUA
3139 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3140 * start waking up. Note that Tcl_FindExecutable will do this, this
3141 * code must be above it! The original warning from
3142 * tkMacOSXAppInit.c is copied below.
3143 *
3144 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3145 * Tcl interpreter for now. It probably should work to do this
3146 * in the other order, but for now it doesn't seem to.
3147 *
3148 */
3149 Tk_MacOSXSetupTkNotifier();
3150#endif
3151
3152
Guido van Rossume187b0e2000-03-27 21:46:29 +00003153 /* This helps the dynamic loader; in Unicode aware Tcl versions
3154 it also helps Tcl find its encodings. */
3155 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00003156
Barry Warsawfa701a81997-01-16 00:15:11 +00003157 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003158 return;
3159
Guido van Rossum43ff8681998-07-14 18:02:13 +00003160#if 0
3161 /* This was not a good idea; through <Destroy> bindings,
3162 Tcl_Finalize() may invoke Python code but at that point the
3163 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003164 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003165#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003166
Guido van Rossum18468821994-06-20 07:49:28 +00003167}