blob: 5b1de8c7a30d2aecdd2920f648c389624f7f89db [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
Guilherme Polo363161a2009-02-06 22:48:07 +000012 Only Tcl/Tk 8.3.1 and later are supported. Older versions are not
13 supported. Use Python 2.6 or older if you cannot upgrade your
14 Tcl/Tk libraries.
Guido van Rossuma80649b2000-03-28 20:07:05 +000015*/
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
Christian Heimese93237d2007-12-19 02:37:44 +0000265#define Tkapp_Check(v) (Py_TYPE(v) == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000266#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000267#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000268
Guido van Rossum35d43371997-08-02 00:09:09 +0000269#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Christian Heimese93237d2007-12-19 02:37:44 +0000270(void *) v, Py_REFCNT(v)))
Guido van Rossum18468821994-06-20 07:49:28 +0000271
Barry Warsawfa701a81997-01-16 00:15:11 +0000272
273
Guido van Rossum18468821994-06-20 07:49:28 +0000274/**** Error Handling ****/
275
276static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000277static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000278static int errorInCmd = 0;
279static PyObject *excInCmd;
280static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000282
Barry Warsawfa701a81997-01-16 00:15:11 +0000283
284
Guido van Rossum18468821994-06-20 07:49:28 +0000285static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000286Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000287{
Barry Warsawfa701a81997-01-16 00:15:11 +0000288 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
289 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000290}
291
Barry Warsawfa701a81997-01-16 00:15:11 +0000292
Barry Warsawfa701a81997-01-16 00:15:11 +0000293
Guido van Rossum18468821994-06-20 07:49:28 +0000294/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000295
Martin v. Löwis28e9ce92003-05-09 08:19:48 +0000296static int Tkinter_busywaitinterval = 20;
297
Guido van Rossum00d93061998-05-28 23:06:38 +0000298#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000299#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000300
Guido van Rossum00d93061998-05-28 23:06:38 +0000301/* Millisecond sleep() for Unix platforms. */
302
303static void
Fred Drake509d79a2000-07-08 04:04:38 +0000304Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000305{
306 /* XXX Too bad if you don't have select(). */
307 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000308 t.tv_sec = milli/1000;
309 t.tv_usec = (milli%1000) * 1000;
310 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
311}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000312#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000313
Martin v. Löwis5b26abb2002-12-28 09:23:09 +0000314/* Wait up to 1s for the mainloop to come up. */
315
316static int
317WaitForMainloop(TkappObject* self)
318{
319 int i;
320 for (i = 0; i < 10; i++) {
321 if (self->dispatching)
322 return 1;
323 Py_BEGIN_ALLOW_THREADS
324 Sleep(100);
325 Py_END_ALLOW_THREADS
326 }
327 if (self->dispatching)
328 return 1;
329 PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
330 return 0;
331}
Martin v. Löwisa9656492003-03-30 08:44:58 +0000332#endif /* WITH_THREAD */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000333
Guido van Rossum00d93061998-05-28 23:06:38 +0000334
Guido van Rossum18468821994-06-20 07:49:28 +0000335static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000336AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000337{
Gregory P. Smithdd96db62008-06-09 04:58:54 +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);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000350 return PyString_AsString(v);
Guido van Rossum2834b972000-10-06 16:58:26 +0000351 }
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);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000362 return PyString_AsString(v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000363 }
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 */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000465 return PyString_FromString(list);
Barry Warsawfa701a81997-01-16 00:15:11 +0000466 }
Guido van Rossum18468821994-06-20 07:49:28 +0000467
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 if (argc == 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000469 v = PyString_FromString("");
Barry Warsawfa701a81997-01-16 00:15:11 +0000470 else if (argc == 1)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000471 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
Martin v. Löwis111c1802008-06-13 07:47:47 +0000493static PyObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000494SplitObj(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 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000533 else if (PyString_Check(arg)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000534 int argc;
535 char **argv;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000536 char *list = PyString_AsString(arg);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000537
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)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000544 return Split(PyString_AsString(arg));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000545 /* 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{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000750 if (self->string && PyString_Check(self->string)) {
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000751 Py_INCREF(self->string);
752 return self->string;
753 }
754 /* XXX Could cache value if it is an ASCII string. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000755 return PyString_FromString(Tcl_GetString(self->value));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000756}
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. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000781 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000782 else {
783 self->string = PyUnicode_DecodeUTF8(s, len, "strict");
784 if (!self->string) {
785 PyErr_Clear();
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000786 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000787 }
788 }
789#else
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000790 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000791#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);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000823 return PyString_FromString(buf);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000824}
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{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000842 return PyString_FromString(obj->value->typePtr->name);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000843}
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
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000911 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 Rossum076d9ee2008-01-03 23:54:04 +0000939 Tcl_UniChar *outbuf = NULL;
Neal Norwitz047f3c72006-06-12 02:06:42 +0000940 Py_ssize_t i;
Guido van Rossum076d9ee2008-01-03 23:54: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)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001002 result = PyString_FromStringAndSize(s, len);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001003 else {
1004 /* Convert UTF-8 to Unicode string */
1005 result = PyUnicode_DecodeUTF8(s, len, "strict");
1006 if (result == NULL) {
1007 PyErr_Clear();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001008 result = PyString_FromStringAndSize(s, len);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001009 }
1010 }
1011#else
Gregory P. Smithdd96db62008-06-09 04:58:54 +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);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001026 return PyString_FromStringAndSize(data, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001027 }
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);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001095 return PyString_FromStringAndSize(c, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001096#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;
Guilherme Polo363161a2009-02-06 22:48:07 +00001113 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001114} 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')
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001207 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum990f5c62000-05-04 15:07:16 +00001208 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();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001214 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');
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001219 res = PyString_FromStringAndSize(s, (int)(p-s));
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001220#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
Guilherme Polo14ff18d2009-02-06 22:26:22 +00001259
1260 Tkapp_CallDeallocArgs(objv, objStore, objc);
1261done:
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001262 /* Wake up calling thread. */
1263 Tcl_MutexLock(&call_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00001264 Tcl_ConditionNotify(e->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001265 Tcl_MutexUnlock(&call_mutex);
1266 return 1;
1267}
1268
1269/* This is the main entry point for calling a Tcl command.
1270 It supports three cases, with regard to threading:
1271 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1272 the context of the calling thread.
1273 2. Tcl is threaded, caller of the command is in the interpreter thread:
1274 Execute the command in the calling thread. Since the Tcl lock will
1275 not be used, we can merge that with case 1.
1276 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1277 the interpreter thread. Allocation of Tcl objects needs to occur in the
1278 interpreter thread, so we ship the PyObject* args to the target thread,
1279 and perform processing there. */
1280
1281static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001282Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001283{
1284 Tcl_Obj *objStore[ARGSZ];
1285 Tcl_Obj **objv = NULL;
1286 int objc, i;
1287 PyObject *res = NULL;
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001288 TkappObject *self = (TkappObject*)selfptr;
Guilherme Polo23fe2a82009-02-02 21:08:32 +00001289 int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001290
Kurt B. Kaiserd67a3b92007-07-05 22:03:39 +00001291 /* If args is a single tuple, replace with contents of tuple */
1292 if (1 == PyTuple_Size(args)){
1293 PyObject* item = PyTuple_GetItem(args, 0);
1294 if (PyTuple_Check(item))
1295 args = item;
1296 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001297#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001298 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1299 /* We cannot call the command directly. Instead, we must
1300 marshal the parameters to the interpreter thread. */
1301 Tkapp_CallEvent *ev;
Guilherme Polo363161a2009-02-06 22:48:07 +00001302 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001303 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001304 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001305 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001306 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1307 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1308 ev->self = self;
1309 ev->args = args;
1310 ev->res = &res;
1311 ev->exc_type = &exc_type;
1312 ev->exc_value = &exc_value;
1313 ev->exc_tb = &exc_tb;
Guilherme Polo363161a2009-02-06 22:48:07 +00001314 ev->done = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001315
Guilherme Polo363161a2009-02-06 22:48:07 +00001316 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001317
1318 if (res == NULL) {
1319 if (exc_type)
1320 PyErr_Restore(exc_type, exc_value, exc_tb);
1321 else
1322 PyErr_SetObject(Tkinter_TclError, exc_value);
1323 }
Guilherme Polo363161a2009-02-06 22:48:07 +00001324 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001325 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001326 else
1327#endif
1328 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001329
1330 objv = Tkapp_CallArgs(args, objStore, &objc);
1331 if (!objv)
1332 return NULL;
1333
1334 ENTER_TCL
1335
1336 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1337
1338 ENTER_OVERLAP
1339
1340 if (i == TCL_ERROR)
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001341 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001342 else
1343 res = Tkapp_CallResult(self);
1344
1345 LEAVE_OVERLAP_TCL
1346
1347 Tkapp_CallDeallocArgs(objv, objStore, objc);
1348 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001349 return res;
1350}
1351
1352
1353static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001354Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001355{
Guido van Rossum212643f1998-04-29 16:22:14 +00001356 /* Could do the same here as for Tkapp_Call(), but this is not used
1357 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1358 way for the user to do what all its Global* variants do (save and
1359 reset the scope pointer, call the local version, restore the saved
1360 scope pointer). */
1361
Guido van Rossum62320c91998-06-15 04:36:09 +00001362 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001363 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001364
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001365 CHECK_TCL_APPARTMENT;
1366
Guido van Rossum62320c91998-06-15 04:36:09 +00001367 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001368 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001369 int err;
1370 ENTER_TCL
1371 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001372 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001373 if (err == TCL_ERROR)
1374 res = Tkinter_Error(self);
1375 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001376 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001377 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001378 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001379 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001380
1381 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001382}
1383
1384static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001385Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001386{
Barry Warsawfa701a81997-01-16 00:15:11 +00001387 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001388 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001389 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001390
Guido van Rossum43713e52000-02-29 13:59:29 +00001391 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001392 return NULL;
1393
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001394 CHECK_TCL_APPARTMENT;
1395
Guido van Rossum00d93061998-05-28 23:06:38 +00001396 ENTER_TCL
1397 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001398 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001399 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001400 res = Tkinter_Error(self);
1401 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001402 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001403 LEAVE_OVERLAP_TCL
1404 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001405}
1406
1407static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001408Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001409{
Barry Warsawfa701a81997-01-16 00:15:11 +00001410 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001411 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001412 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001413
Guido van Rossum43713e52000-02-29 13:59:29 +00001414 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001415 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001416
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001417 CHECK_TCL_APPARTMENT;
1418
Guido van Rossum00d93061998-05-28 23:06:38 +00001419 ENTER_TCL
1420 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001421 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001422 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001423 res = Tkinter_Error(self);
1424 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001425 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001426 LEAVE_OVERLAP_TCL
1427 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001428}
1429
1430static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001431Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001432{
Barry Warsawfa701a81997-01-16 00:15:11 +00001433 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001434 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001435 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001436
Guido van Rossum43713e52000-02-29 13:59:29 +00001437 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001438 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001439
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001440 CHECK_TCL_APPARTMENT;
1441
Guido van Rossum00d93061998-05-28 23:06:38 +00001442 ENTER_TCL
1443 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001444 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001445 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001446 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001447
Guido van Rossum62320c91998-06-15 04:36:09 +00001448 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001449 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001450 LEAVE_OVERLAP_TCL
1451 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001452}
1453
1454static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001455Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001456{
Barry Warsawfa701a81997-01-16 00:15:11 +00001457 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001458 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001459 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001460
Guido van Rossum35d43371997-08-02 00:09:09 +00001461 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001462 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001463
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001464 CHECK_TCL_APPARTMENT;
1465
Guido van Rossum00d93061998-05-28 23:06:38 +00001466 ENTER_TCL
1467 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001468 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001469 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001470 res = Tkinter_Error(self);
1471 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001472 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001473 LEAVE_OVERLAP_TCL
1474 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001475}
1476
1477static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001478Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001479{
Barry Warsawfa701a81997-01-16 00:15:11 +00001480 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001481
Guido van Rossum43713e52000-02-29 13:59:29 +00001482 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001483 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001484 CHECK_TCL_APPARTMENT;
1485
Guido van Rossum00d93061998-05-28 23:06:38 +00001486 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001487 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001488 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001489
Barry Warsawfa701a81997-01-16 00:15:11 +00001490 Py_INCREF(Py_None);
1491 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001492}
1493
Barry Warsawfa701a81997-01-16 00:15:11 +00001494
1495
Guido van Rossum18468821994-06-20 07:49:28 +00001496/** Tcl Variable **/
1497
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001498TCL_DECLARE_MUTEX(var_mutex)
1499
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001500typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001501typedef struct VarEvent {
1502 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001503 PyObject *self;
1504 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001505 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001506 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001507 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001508 PyObject **exc_type;
1509 PyObject **exc_val;
Guilherme Polo363161a2009-02-06 22:48:07 +00001510 Tcl_Condition *cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001511} VarEvent;
1512
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001513static int
1514varname_converter(PyObject *in, void *_out)
1515{
1516 char **out = (char**)_out;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001517 if (PyString_Check(in)) {
1518 *out = PyString_AsString(in);
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001519 return 1;
1520 }
1521 if (PyTclObject_Check(in)) {
1522 *out = PyTclObject_TclString(in);
1523 return 1;
1524 }
1525 /* XXX: Should give diagnostics. */
1526 return 0;
1527}
1528
Martin v. Löwis111c1802008-06-13 07:47:47 +00001529static void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001530var_perform(VarEvent *ev)
1531{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001532 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1533 if (!*(ev->res)) {
1534 PyObject *exc, *val, *tb;
1535 PyErr_Fetch(&exc, &val, &tb);
1536 PyErr_NormalizeException(&exc, &val, &tb);
1537 *(ev->exc_type) = exc;
1538 *(ev->exc_val) = val;
1539 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001540 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001541
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001542}
1543
1544static int
1545var_proc(VarEvent* ev, int flags)
1546{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001547 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001548 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001549 Tcl_MutexLock(&var_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00001550 Tcl_ConditionNotify(ev->cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001551 Tcl_MutexUnlock(&var_mutex);
1552 LEAVE_PYTHON
1553 return 1;
1554}
1555
1556static PyObject*
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001557var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001558{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001559 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisa9656492003-03-30 08:44:58 +00001560#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001561 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001562 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001563 VarEvent *ev;
1564 PyObject *res, *exc_type, *exc_val;
Guilherme Polo363161a2009-02-06 22:48:07 +00001565 Tcl_Condition cond = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001566
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001567 /* The current thread is not the interpreter thread. Marshal
1568 the call to the interpreter thread, then wait for
1569 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001570 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001571 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001572
1573 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1574
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001575 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001576 ev->args = args;
1577 ev->flags = flags;
1578 ev->func = func;
1579 ev->res = &res;
1580 ev->exc_type = &exc_type;
1581 ev->exc_val = &exc_val;
Guilherme Polo363161a2009-02-06 22:48:07 +00001582 ev->cond = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001583 ev->ev.proc = (Tcl_EventProc*)var_proc;
Guilherme Polo363161a2009-02-06 22:48:07 +00001584 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
1585 Tcl_ConditionFinalize(&cond);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001586 if (!res) {
1587 PyErr_SetObject(exc_type, exc_val);
1588 Py_DECREF(exc_type);
1589 Py_DECREF(exc_val);
1590 return NULL;
1591 }
1592 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001593 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001594#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001595 /* Tcl is not threaded, or this is the interpreter thread. */
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001596 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001597}
1598
Guido van Rossum18468821994-06-20 07:49:28 +00001599static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001600SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001601{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001602 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001603 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001604 PyObject *res = NULL;
1605 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001606
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001607 if (PyArg_ParseTuple(args, "O&O:setvar",
1608 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001609 /* XXX Acquire tcl lock??? */
1610 newval = AsObj(newValue);
1611 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001612 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001613 ENTER_TCL
1614 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1615 newval, flags);
1616 ENTER_OVERLAP
1617 if (!ok)
1618 Tkinter_Error(self);
1619 else {
1620 res = Py_None;
1621 Py_INCREF(res);
1622 }
1623 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001624 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001625 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001626 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001627 if (PyArg_ParseTuple(args, "ssO:setvar",
1628 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001629 /* XXX must hold tcl lock already??? */
1630 newval = AsObj(newValue);
1631 ENTER_TCL
1632 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1633 ENTER_OVERLAP
1634 if (!ok)
1635 Tkinter_Error(self);
1636 else {
1637 res = Py_None;
1638 Py_INCREF(res);
1639 }
1640 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001641 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001642 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001643 return NULL;
1644 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001645 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001646 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001647}
1648
1649static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001650Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001651{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001652 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001653}
1654
1655static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001656Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001657{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001658 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001659}
1660
Barry Warsawfa701a81997-01-16 00:15:11 +00001661
1662
Guido van Rossum18468821994-06-20 07:49:28 +00001663static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001664GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001665{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001666 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001667 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001668 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001669
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001670 if (!PyArg_ParseTuple(args, "O&|s:getvar",
1671 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001672 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001673
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001674 ENTER_TCL
1675 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1676 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001677 if (tres == NULL) {
1678 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1679 } else {
1680 if (((TkappObject*)self)->wantobjects) {
1681 res = FromObj(self, tres);
1682 }
1683 else {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001684 res = PyString_FromString(Tcl_GetString(tres));
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001685 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001686 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001687 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001688 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001689}
1690
1691static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001692Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001693{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001694 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001695}
1696
1697static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001698Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001699{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001700 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001701}
1702
Barry Warsawfa701a81997-01-16 00:15:11 +00001703
1704
Guido van Rossum18468821994-06-20 07:49:28 +00001705static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001706UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001707{
Guido van Rossum35d43371997-08-02 00:09:09 +00001708 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001709 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001710 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001711
Guido van Rossum43713e52000-02-29 13:59:29 +00001712 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001713 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001714
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001715 ENTER_TCL
1716 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1717 ENTER_OVERLAP
1718 if (code == TCL_ERROR)
1719 res = Tkinter_Error(self);
1720 else {
1721 Py_INCREF(Py_None);
1722 res = Py_None;
1723 }
1724 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001725 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001726}
1727
1728static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001729Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001730{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001731 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001732}
1733
1734static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001735Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001736{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001737 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001738}
1739
Barry Warsawfa701a81997-01-16 00:15:11 +00001740
1741
Guido van Rossum18468821994-06-20 07:49:28 +00001742/** Tcl to Python **/
1743
1744static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001745Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001746{
Barry Warsawfa701a81997-01-16 00:15:11 +00001747 char *s;
1748 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001749
Martin v. Löwisffad6332002-11-26 09:28:05 +00001750 if (PyTuple_Size(args) == 1) {
1751 PyObject* o = PyTuple_GetItem(args, 0);
1752 if (PyInt_Check(o)) {
1753 Py_INCREF(o);
1754 return o;
1755 }
1756 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001757 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001758 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001759 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001760 return Tkinter_Error(self);
1761 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001762}
1763
1764static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001765Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001766{
Barry Warsawfa701a81997-01-16 00:15:11 +00001767 char *s;
1768 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001769
Martin v. Löwisffad6332002-11-26 09:28:05 +00001770 if (PyTuple_Size(args) == 1) {
1771 PyObject *o = PyTuple_GetItem(args, 0);
1772 if (PyFloat_Check(o)) {
1773 Py_INCREF(o);
1774 return o;
1775 }
1776 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001777 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001778 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001779 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001780 return Tkinter_Error(self);
1781 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001782}
1783
1784static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001785Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001786{
Barry Warsawfa701a81997-01-16 00:15:11 +00001787 char *s;
1788 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001789
Martin v. Löwisffad6332002-11-26 09:28:05 +00001790 if (PyTuple_Size(args) == 1) {
1791 PyObject *o = PyTuple_GetItem(args, 0);
1792 if (PyInt_Check(o)) {
1793 Py_INCREF(o);
1794 return o;
1795 }
1796 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001797 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001798 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001799 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1800 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001801 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001802}
1803
1804static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001805Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001806{
Barry Warsawfa701a81997-01-16 00:15:11 +00001807 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001808 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001809 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001810
Guido van Rossum43713e52000-02-29 13:59:29 +00001811 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001812 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001813
1814 CHECK_TCL_APPARTMENT;
1815
Guido van Rossum00d93061998-05-28 23:06:38 +00001816 ENTER_TCL
1817 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001818 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001819 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001820 res = Tkinter_Error(self);
1821 else
1822 res = Py_BuildValue("s", Tkapp_Result(self));
1823 LEAVE_OVERLAP_TCL
1824 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001825}
1826
1827static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001828Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001829{
Barry Warsawfa701a81997-01-16 00:15:11 +00001830 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001831 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001832 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001833 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001834
Guido van Rossum43713e52000-02-29 13:59:29 +00001835 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001836 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001837
1838 CHECK_TCL_APPARTMENT;
1839
Guido van Rossum00d93061998-05-28 23:06:38 +00001840 ENTER_TCL
1841 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001842 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001843 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001844 res = Tkinter_Error(self);
1845 else
1846 res = Py_BuildValue("l", v);
1847 LEAVE_OVERLAP_TCL
1848 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001849}
1850
1851static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001852Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001853{
Barry Warsawfa701a81997-01-16 00:15:11 +00001854 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001855 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001856 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001857 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001858
Guido van Rossum43713e52000-02-29 13:59:29 +00001859 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001860 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001861 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001862 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001863 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001864 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001865 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001866 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001867 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001868 res = Tkinter_Error(self);
1869 else
1870 res = Py_BuildValue("d", v);
1871 LEAVE_OVERLAP_TCL
1872 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001873}
1874
1875static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001876Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001877{
Barry Warsawfa701a81997-01-16 00:15:11 +00001878 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001879 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001880 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001881 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001882
Guido van Rossum43713e52000-02-29 13:59:29 +00001883 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001884 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001885 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001886 ENTER_TCL
1887 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001888 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001889 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001890 res = Tkinter_Error(self);
1891 else
1892 res = Py_BuildValue("i", v);
1893 LEAVE_OVERLAP_TCL
1894 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001895}
1896
Barry Warsawfa701a81997-01-16 00:15:11 +00001897
1898
Guido van Rossum18468821994-06-20 07:49:28 +00001899static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001900Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001901{
Barry Warsawfa701a81997-01-16 00:15:11 +00001902 char *list;
1903 int argc;
1904 char **argv;
1905 PyObject *v;
1906 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001907
Martin v. Löwisffad6332002-11-26 09:28:05 +00001908 if (PyTuple_Size(args) == 1) {
1909 v = PyTuple_GetItem(args, 0);
1910 if (PyTuple_Check(v)) {
1911 Py_INCREF(v);
1912 return v;
1913 }
1914 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001915 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001916 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001917
Neal Norwitzd1c55102003-05-29 00:17:03 +00001918 if (Tcl_SplitList(Tkapp_Interp(self), list,
1919 &argc, &argv) == TCL_ERROR) {
1920 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001921 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001922 }
Guido van Rossum18468821994-06-20 07:49:28 +00001923
Barry Warsawfa701a81997-01-16 00:15:11 +00001924 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001925 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001926
Barry Warsawfa701a81997-01-16 00:15:11 +00001927 for (i = 0; i < argc; i++) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001928 PyObject *s = PyString_FromString(argv[i]);
Barry Warsawfa701a81997-01-16 00:15:11 +00001929 if (!s || PyTuple_SetItem(v, i, s)) {
1930 Py_DECREF(v);
1931 v = NULL;
1932 goto finally;
1933 }
1934 }
Guido van Rossum18468821994-06-20 07:49:28 +00001935
Barry Warsawfa701a81997-01-16 00:15:11 +00001936 finally:
1937 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001938 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001939 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001940}
1941
1942static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001943Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001944{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001945 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001946 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001947
Martin v. Löwisffad6332002-11-26 09:28:05 +00001948 if (PyTuple_Size(args) == 1) {
1949 PyObject* o = PyTuple_GetItem(args, 0);
1950 if (PyTuple_Check(o)) {
1951 o = SplitObj(o);
1952 return o;
1953 }
1954 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001955 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001956 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00001957 v = Split(list);
1958 PyMem_Free(list);
1959 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001960}
1961
1962static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001963Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001964{
Barry Warsawfa701a81997-01-16 00:15:11 +00001965 char *s = Merge(args);
1966 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001967
Barry Warsawfa701a81997-01-16 00:15:11 +00001968 if (s) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001969 res = PyString_FromString(s);
Barry Warsawfa701a81997-01-16 00:15:11 +00001970 ckfree(s);
1971 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001972
1973 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001974}
1975
Barry Warsawfa701a81997-01-16 00:15:11 +00001976
1977
Guido van Rossum18468821994-06-20 07:49:28 +00001978/** Tcl Command **/
1979
Guido van Rossum00d93061998-05-28 23:06:38 +00001980/* Client data struct */
1981typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001982 PyObject *self;
1983 PyObject *func;
1984} PythonCmd_ClientData;
1985
1986static int
Fred Drake509d79a2000-07-08 04:04:38 +00001987PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001988{
1989 errorInCmd = 1;
1990 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1991 LEAVE_PYTHON
1992 return TCL_ERROR;
1993}
1994
Guido van Rossum18468821994-06-20 07:49:28 +00001995/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001996 * function or method.
1997 */
Guido van Rossum18468821994-06-20 07:49:28 +00001998static int
Fred Drake509d79a2000-07-08 04:04:38 +00001999PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00002000{
Guido van Rossum00d93061998-05-28 23:06:38 +00002001 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002002 PyObject *self, *func, *arg, *res;
Guido van Rossum2834b972000-10-06 16:58:26 +00002003 int i, rv;
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002004 Tcl_Obj *obj_res;
Guido van Rossum18468821994-06-20 07:49:28 +00002005
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002006 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002007
Barry Warsawfa701a81997-01-16 00:15:11 +00002008 /* TBD: no error checking here since we know, via the
2009 * Tkapp_CreateCommand() that the client data is a two-tuple
2010 */
Guido van Rossum00d93061998-05-28 23:06:38 +00002011 self = data->self;
2012 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00002013
Barry Warsawfa701a81997-01-16 00:15:11 +00002014 /* Create argument list (argv1, ..., argvN) */
2015 if (!(arg = PyTuple_New(argc - 1)))
2016 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00002017
Barry Warsawfa701a81997-01-16 00:15:11 +00002018 for (i = 0; i < (argc - 1); i++) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002019 PyObject *s = PyString_FromString(argv[i + 1]);
Barry Warsawfa701a81997-01-16 00:15:11 +00002020 if (!s || PyTuple_SetItem(arg, i, s)) {
2021 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00002022 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00002023 }
2024 }
2025 res = PyEval_CallObject(func, arg);
2026 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00002027
Barry Warsawfa701a81997-01-16 00:15:11 +00002028 if (res == NULL)
2029 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00002030
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002031 obj_res = AsObj(res);
2032 if (obj_res == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002033 Py_DECREF(res);
2034 return PythonCmd_Error(interp);
2035 }
Guido van Rossum2834b972000-10-06 16:58:26 +00002036 else {
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002037 Tcl_SetObjResult(Tkapp_Interp(self), obj_res);
Guido van Rossum2834b972000-10-06 16:58:26 +00002038 rv = TCL_OK;
2039 }
2040
Barry Warsawfa701a81997-01-16 00:15:11 +00002041 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00002042
Guido van Rossum00d93061998-05-28 23:06:38 +00002043 LEAVE_PYTHON
2044
Guido van Rossum2834b972000-10-06 16:58:26 +00002045 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002046}
2047
2048static void
Fred Drake509d79a2000-07-08 04:04:38 +00002049PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002050{
Guido van Rossum00d93061998-05-28 23:06:38 +00002051 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2052
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002053 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002054 Py_XDECREF(data->self);
2055 Py_XDECREF(data->func);
2056 PyMem_DEL(data);
2057 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002058}
2059
Barry Warsawfa701a81997-01-16 00:15:11 +00002060
2061
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002062
2063TCL_DECLARE_MUTEX(command_mutex)
2064
2065typedef struct CommandEvent{
2066 Tcl_Event ev;
2067 Tcl_Interp* interp;
2068 char *name;
2069 int create;
2070 int *status;
2071 ClientData *data;
Guilherme Polo363161a2009-02-06 22:48:07 +00002072 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002073} CommandEvent;
2074
2075static int
2076Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002077{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002078 if (ev->create)
2079 *ev->status = Tcl_CreateCommand(
2080 ev->interp, ev->name, PythonCmd,
2081 ev->data, PythonCmdDelete) == NULL;
2082 else
2083 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2084 Tcl_MutexLock(&command_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00002085 Tcl_ConditionNotify(ev->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002086 Tcl_MutexUnlock(&command_mutex);
2087 return 1;
2088}
2089
2090static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002091Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002092{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002093 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002094 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002095 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002096 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002097 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002098
Guido van Rossum43713e52000-02-29 13:59:29 +00002099 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002100 return NULL;
2101 if (!PyCallable_Check(func)) {
2102 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002103 return NULL;
2104 }
Guido van Rossum18468821994-06-20 07:49:28 +00002105
Martin v. Löwisa9656492003-03-30 08:44:58 +00002106#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002107 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002108 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002109 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002110#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002111
Guido van Rossum00d93061998-05-28 23:06:38 +00002112 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002113 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002114 return PyErr_NoMemory();
Neal Norwitzce5b3c32006-07-16 02:02:57 +00002115 Py_INCREF(self);
2116 Py_INCREF(func);
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002117 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002118 data->func = func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002119
2120 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo363161a2009-02-06 22:48:07 +00002121 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002122 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2123 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2124 ev->interp = self->interp;
2125 ev->create = 1;
2126 ev->name = cmdName;
2127 ev->data = (ClientData)data;
2128 ev->status = &err;
Guilherme Polo363161a2009-02-06 22:48:07 +00002129 ev->done = &cond;
2130 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
2131 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002132 }
2133 else {
2134 ENTER_TCL
2135 err = Tcl_CreateCommand(
2136 Tkapp_Interp(self), cmdName, PythonCmd,
2137 (ClientData)data, PythonCmdDelete) == NULL;
2138 LEAVE_TCL
2139 }
2140 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002141 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002142 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002143 return NULL;
2144 }
Guido van Rossum18468821994-06-20 07:49:28 +00002145
Barry Warsawfa701a81997-01-16 00:15:11 +00002146 Py_INCREF(Py_None);
2147 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002148}
2149
Barry Warsawfa701a81997-01-16 00:15:11 +00002150
2151
Guido van Rossum18468821994-06-20 07:49:28 +00002152static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002153Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002154{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002155 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002156 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002157 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002158
Guido van Rossum43713e52000-02-29 13:59:29 +00002159 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002160 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002161 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo363161a2009-02-06 22:48:07 +00002162 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002163 CommandEvent *ev;
2164 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2165 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2166 ev->interp = self->interp;
2167 ev->create = 0;
2168 ev->name = cmdName;
2169 ev->status = &err;
Guilherme Polo363161a2009-02-06 22:48:07 +00002170 ev->done = &cond;
2171 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002172 &command_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00002173 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002174 }
2175 else {
2176 ENTER_TCL
2177 err = Tcl_DeleteCommand(self->interp, cmdName);
2178 LEAVE_TCL
2179 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002180 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002181 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2182 return NULL;
2183 }
2184 Py_INCREF(Py_None);
2185 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002186}
2187
Barry Warsawfa701a81997-01-16 00:15:11 +00002188
2189
Guido van Rossum00d93061998-05-28 23:06:38 +00002190#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002191/** File Handler **/
2192
Guido van Rossum00d93061998-05-28 23:06:38 +00002193typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002194 PyObject *func;
2195 PyObject *file;
2196 int id;
2197 struct _fhcdata *next;
2198} FileHandler_ClientData;
2199
2200static FileHandler_ClientData *HeadFHCD;
2201
2202static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002203NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002204{
2205 FileHandler_ClientData *p;
2206 p = PyMem_NEW(FileHandler_ClientData, 1);
2207 if (p != NULL) {
2208 Py_XINCREF(func);
2209 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002210 p->func = func;
2211 p->file = file;
2212 p->id = id;
2213 p->next = HeadFHCD;
2214 HeadFHCD = p;
2215 }
2216 return p;
2217}
2218
2219static void
Fred Drake509d79a2000-07-08 04:04:38 +00002220DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002221{
2222 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002223
2224 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002225 while ((p = *pp) != NULL) {
2226 if (p->id == id) {
2227 *pp = p->next;
2228 Py_XDECREF(p->func);
2229 Py_XDECREF(p->file);
2230 PyMem_DEL(p);
2231 }
2232 else
2233 pp = &p->next;
2234 }
2235}
2236
Guido van Rossuma597dde1995-01-10 20:56:29 +00002237static void
Fred Drake509d79a2000-07-08 04:04:38 +00002238FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002239{
Guido van Rossum00d93061998-05-28 23:06:38 +00002240 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002241 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002242
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002243 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002244 func = data->func;
2245 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002246
Barry Warsawfa701a81997-01-16 00:15:11 +00002247 arg = Py_BuildValue("(Oi)", file, (long) mask);
2248 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002249 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002250
2251 if (res == NULL) {
2252 errorInCmd = 1;
2253 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2254 }
2255 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002256 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002257}
2258
Guido van Rossum18468821994-06-20 07:49:28 +00002259static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002260Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2261 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002262{
Guido van Rossum00d93061998-05-28 23:06:38 +00002263 FileHandler_ClientData *data;
2264 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002265 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002266
Guilherme Poloe7f14032009-01-03 21:51:09 +00002267 if (!self && Py_Py3kWarningFlag) {
2268 if (PyErr_Warn(PyExc_DeprecationWarning,
2269 "_tkinter.createfilehandler is gone in 3.x") < 0)
2270 return NULL;
2271 }
2272
Guido van Rossum2834b972000-10-06 16:58:26 +00002273 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2274 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002275 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002276
Martin v. Löwisa9656492003-03-30 08:44:58 +00002277#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002278 if (!self && !tcl_lock) {
2279 /* We don't have the Tcl lock since Tcl is threaded. */
2280 PyErr_SetString(PyExc_RuntimeError,
2281 "_tkinter.createfilehandler not supported "
2282 "for threaded Tcl");
2283 return NULL;
2284 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002285#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002286
2287 if (self) {
2288 CHECK_TCL_APPARTMENT;
2289 }
2290
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002291 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002292 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002293 return NULL;
2294 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002295 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002296 return NULL;
2297 }
2298
Guido van Rossuma80649b2000-03-28 20:07:05 +00002299 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002300 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002301 return NULL;
2302
Barry Warsawfa701a81997-01-16 00:15:11 +00002303 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002304 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002305 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002306 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002307 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002308 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002309}
2310
2311static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002312Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002313{
Barry Warsawfa701a81997-01-16 00:15:11 +00002314 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002315 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002316
Guilherme Poloe7f14032009-01-03 21:51:09 +00002317 if (!self && Py_Py3kWarningFlag) {
2318 if (PyErr_Warn(PyExc_DeprecationWarning,
2319 "_tkinter.deletefilehandler is gone in 3.x") < 0)
2320 return NULL;
2321 }
2322
Guido van Rossum43713e52000-02-29 13:59:29 +00002323 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002324 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002325
Martin v. Löwisa9656492003-03-30 08:44:58 +00002326#ifdef WITH_THREAD
Neal Norwitz12e22172003-03-03 21:16:39 +00002327 if (!self && !tcl_lock) {
2328 /* We don't have the Tcl lock since Tcl is threaded. */
2329 PyErr_SetString(PyExc_RuntimeError,
2330 "_tkinter.deletefilehandler not supported "
2331 "for threaded Tcl");
2332 return NULL;
2333 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002334#endif
Neal Norwitz12e22172003-03-03 21:16:39 +00002335
2336 if (self) {
2337 CHECK_TCL_APPARTMENT;
2338 }
2339
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002340 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002341 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002342 return NULL;
2343
Guido van Rossuma80649b2000-03-28 20:07:05 +00002344 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002345
Barry Warsawfa701a81997-01-16 00:15:11 +00002346 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002347 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002348 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002349 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002350 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002351 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002352}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002353#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002354
Barry Warsawfa701a81997-01-16 00:15:11 +00002355
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002356/**** Tktt Object (timer token) ****/
2357
Jeremy Hylton938ace62002-07-17 16:30:39 +00002358static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002359
Guido van Rossum00d93061998-05-28 23:06:38 +00002360typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002361 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002362 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002363 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002364} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002365
2366static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002367Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002368{
Barry Warsawfa701a81997-01-16 00:15:11 +00002369 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002370 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002371
Guido van Rossum43713e52000-02-29 13:59:29 +00002372 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002373 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002374 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002375 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002376 v->token = NULL;
2377 }
2378 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002379 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002380 Py_DECREF(func);
2381 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002382 }
2383 Py_INCREF(Py_None);
2384 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002385}
2386
2387static PyMethodDef Tktt_methods[] =
2388{
Neal Norwitzb0493252002-03-31 14:44:22 +00002389 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002390 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002391};
2392
2393static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002394Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002395{
Barry Warsawfa701a81997-01-16 00:15:11 +00002396 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002397
Guido van Rossumb18618d2000-05-03 23:44:39 +00002398 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002399 if (v == NULL)
2400 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002401
Guido van Rossum00d93061998-05-28 23:06:38 +00002402 Py_INCREF(func);
2403 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002404 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002405
2406 /* Extra reference, deleted when called or when handler is deleted */
2407 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002408 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002409}
2410
2411static void
Fred Drake509d79a2000-07-08 04:04:38 +00002412Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002413{
Guido van Rossum00d93061998-05-28 23:06:38 +00002414 TkttObject *v = (TkttObject *)self;
2415 PyObject *func = v->func;
2416
2417 Py_XDECREF(func);
2418
Guido van Rossumb18618d2000-05-03 23:44:39 +00002419 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002420}
2421
Guido van Rossum597ac201998-05-12 14:36:19 +00002422static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002423Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002424{
Barry Warsawfa701a81997-01-16 00:15:11 +00002425 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002426 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002427
Tim Peters885d4572001-11-28 20:27:42 +00002428 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002429 v->func == NULL ? ", handler deleted" : "");
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002430 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002431}
2432
2433static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002434Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002435{
Barry Warsawfa701a81997-01-16 00:15:11 +00002436 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002437}
2438
2439static PyTypeObject Tktt_Type =
2440{
Martin v. Löwis68192102007-07-21 06:55:02 +00002441 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002442 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002443 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002444 0, /*tp_itemsize */
2445 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002446 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00002447 Tktt_GetAttr, /*tp_getattr */
2448 0, /*tp_setattr */
2449 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00002450 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002451 0, /*tp_as_number */
2452 0, /*tp_as_sequence */
2453 0, /*tp_as_mapping */
2454 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002455};
2456
Barry Warsawfa701a81997-01-16 00:15:11 +00002457
2458
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002459/** Timer Handler **/
2460
2461static void
Fred Drake509d79a2000-07-08 04:04:38 +00002462TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002463{
Guido van Rossum00d93061998-05-28 23:06:38 +00002464 TkttObject *v = (TkttObject *)clientData;
2465 PyObject *func = v->func;
2466 PyObject *res;
2467
2468 if (func == NULL)
2469 return;
2470
2471 v->func = NULL;
2472
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002473 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002474
2475 res = PyEval_CallObject(func, NULL);
2476 Py_DECREF(func);
2477 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002478
Barry Warsawfa701a81997-01-16 00:15:11 +00002479 if (res == NULL) {
2480 errorInCmd = 1;
2481 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2482 }
2483 else
2484 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002485
2486 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002487}
2488
2489static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002490Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002491{
Barry Warsawfa701a81997-01-16 00:15:11 +00002492 int milliseconds;
2493 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002494 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002495
Guilherme Poloe7f14032009-01-03 21:51:09 +00002496 if (!self && Py_Py3kWarningFlag) {
2497 if (PyErr_Warn(PyExc_DeprecationWarning,
2498 "_tkinter.createtimerhandler is gone in 3.x") < 0)
2499 return NULL;
2500 }
2501
Guido van Rossum2834b972000-10-06 16:58:26 +00002502 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2503 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002504 return NULL;
2505 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002506 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002507 return NULL;
2508 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002509
Martin v. Löwisa9656492003-03-30 08:44:58 +00002510#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002511 if (!self && !tcl_lock) {
2512 /* We don't have the Tcl lock since Tcl is threaded. */
2513 PyErr_SetString(PyExc_RuntimeError,
2514 "_tkinter.createtimerhandler not supported "
2515 "for threaded Tcl");
2516 return NULL;
2517 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002518#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002519
2520 if (self) {
2521 CHECK_TCL_APPARTMENT;
2522 }
2523
Guido van Rossum00d93061998-05-28 23:06:38 +00002524 v = Tktt_New(func);
Neal Norwitz5f17d9a2006-08-12 02:33:36 +00002525 if (v) {
2526 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2527 (ClientData)v);
2528 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002529
Guido van Rossum00d93061998-05-28 23:06:38 +00002530 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002531}
2532
Barry Warsawfa701a81997-01-16 00:15:11 +00002533
Guido van Rossum18468821994-06-20 07:49:28 +00002534/** Event Loop **/
2535
Guido van Rossum18468821994-06-20 07:49:28 +00002536static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002537Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002538{
Barry Warsawfa701a81997-01-16 00:15:11 +00002539 int threshold = 0;
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002540 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002541#ifdef WITH_THREAD
2542 PyThreadState *tstate = PyThreadState_Get();
2543#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002544
Guilherme Poloe7f14032009-01-03 21:51:09 +00002545 if (!self && Py_Py3kWarningFlag) {
2546 if (PyErr_Warn(PyExc_DeprecationWarning,
2547 "_tkinter.mainloop is gone in 3.x") < 0)
2548 return NULL;
2549 }
2550
Guido van Rossum43713e52000-02-29 13:59:29 +00002551 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002552 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002553
Martin v. Löwisa9656492003-03-30 08:44:58 +00002554#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002555 if (!self && !tcl_lock) {
2556 /* We don't have the Tcl lock since Tcl is threaded. */
2557 PyErr_SetString(PyExc_RuntimeError,
2558 "_tkinter.mainloop not supported "
2559 "for threaded Tcl");
2560 return NULL;
2561 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002562#endif
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002563
2564 if (self) {
2565 CHECK_TCL_APPARTMENT;
2566 self->dispatching = 1;
2567 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002568
Barry Warsawfa701a81997-01-16 00:15:11 +00002569 quitMainLoop = 0;
2570 while (Tk_GetNumMainWindows() > threshold &&
2571 !quitMainLoop &&
2572 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002573 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002574 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002575
2576#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002577 if (self && self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002578 /* Allow other Python threads to run. */
2579 ENTER_TCL
2580 result = Tcl_DoOneEvent(0);
2581 LEAVE_TCL
2582 }
2583 else {
2584 Py_BEGIN_ALLOW_THREADS
2585 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2586 tcl_tstate = tstate;
2587 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2588 tcl_tstate = NULL;
2589 if(tcl_lock)PyThread_release_lock(tcl_lock);
2590 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002591 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002592 Py_END_ALLOW_THREADS
2593 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002594#else
2595 result = Tcl_DoOneEvent(0);
2596#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002597
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002598 if (PyErr_CheckSignals() != 0) {
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002599 if (self)
2600 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002601 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002602 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002603 if (result < 0)
2604 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002605 }
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002606 if (self)
2607 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002608 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002609
Barry Warsawfa701a81997-01-16 00:15:11 +00002610 if (errorInCmd) {
2611 errorInCmd = 0;
2612 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2613 excInCmd = valInCmd = trbInCmd = NULL;
2614 return NULL;
2615 }
2616 Py_INCREF(Py_None);
2617 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002618}
2619
2620static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002621Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002622{
Guido van Rossum35d43371997-08-02 00:09:09 +00002623 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002624 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002625
Guilherme Poloe7f14032009-01-03 21:51:09 +00002626 if (!self && Py_Py3kWarningFlag) {
2627 if (PyErr_Warn(PyExc_DeprecationWarning,
2628 "_tkinter.dooneevent is gone in 3.x") < 0)
2629 return NULL;
2630 }
2631
Guido van Rossum43713e52000-02-29 13:59:29 +00002632 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002633 return NULL;
2634
Guido van Rossum00d93061998-05-28 23:06:38 +00002635 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002636 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002637 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002638 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002639}
2640
2641static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002642Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002643{
2644
Guilherme Poloe7f14032009-01-03 21:51:09 +00002645 if (!self && Py_Py3kWarningFlag) {
2646 if (PyErr_Warn(PyExc_DeprecationWarning,
2647 "_tkinter.createfilehandler is gone in 3.x") < 0)
2648 return NULL;
2649 }
2650
Guido van Rossum43713e52000-02-29 13:59:29 +00002651 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002652 return NULL;
2653
2654 quitMainLoop = 1;
2655 Py_INCREF(Py_None);
2656 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002657}
2658
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002659static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002660Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002661{
2662
Guido van Rossum43713e52000-02-29 13:59:29 +00002663 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002664 return NULL;
2665
2666 return PyInt_FromLong((long)Tkapp_Interp(self));
2667}
2668
David Aschere2b4b322004-02-18 05:59:53 +00002669static PyObject *
2670Tkapp_TkInit(PyObject *self, PyObject *args)
2671{
Martin v. Löwis86725192006-05-01 06:28:01 +00002672 static int has_failed;
David Aschere2b4b322004-02-18 05:59:53 +00002673 Tcl_Interp *interp = Tkapp_Interp(self);
Neal Norwitz44dbae82004-02-19 02:44:22 +00002674 Tk_Window main_window;
David Aschere2b4b322004-02-18 05:59:53 +00002675 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002676 int err;
Neal Norwitz44dbae82004-02-19 02:44:22 +00002677 main_window = Tk_MainWindow(interp);
David Aschere2b4b322004-02-18 05:59:53 +00002678
Martin v. Löwis86725192006-05-01 06:28:01 +00002679 /* In all current versions of Tk (including 8.4.13), Tk_Init
2680 deadlocks on the second call when the first call failed.
2681 To avoid the deadlock, we just refuse the second call through
2682 a static variable. */
2683 if (has_failed) {
2684 PyErr_SetString(Tkinter_TclError,
2685 "Calling Tk_Init again after a previous call failed might deadlock");
2686 return NULL;
2687 }
2688
David Aschere2b4b322004-02-18 05:59:53 +00002689 /* We want to guard against calling Tk_Init() multiple times */
2690 CHECK_TCL_APPARTMENT;
2691 ENTER_TCL
2692 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2693 ENTER_OVERLAP
2694 if (err == TCL_ERROR) {
Martin v. Löwis86725192006-05-01 06:28:01 +00002695 /* This sets an exception, but we cannot return right
2696 away because we need to exit the overlap first. */
2697 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002698 } else {
2699 _tk_exists = Tkapp_Result(self);
2700 }
2701 LEAVE_OVERLAP_TCL
2702 if (err == TCL_ERROR) {
2703 return NULL;
2704 }
2705 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2706 if (Tk_Init(interp) == TCL_ERROR) {
2707 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
Martin v. Löwis86725192006-05-01 06:28:01 +00002708 has_failed = 1;
David Aschere2b4b322004-02-18 05:59:53 +00002709 return NULL;
2710 }
2711 }
2712 Py_INCREF(Py_None);
2713 return Py_None;
2714}
Barry Warsawfa701a81997-01-16 00:15:11 +00002715
Martin v. Löwisffad6332002-11-26 09:28:05 +00002716static PyObject *
2717Tkapp_WantObjects(PyObject *self, PyObject *args)
2718{
2719
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002720 int wantobjects = -1;
2721 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002722 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002723 if (wantobjects == -1)
2724 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002725 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002726
2727 Py_INCREF(Py_None);
2728 return Py_None;
2729}
2730
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002731static PyObject *
2732Tkapp_WillDispatch(PyObject *self, PyObject *args)
2733{
2734
2735 ((TkappObject*)self)->dispatching = 1;
2736
2737 Py_INCREF(Py_None);
2738 return Py_None;
2739}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002740
Barry Warsawfa701a81997-01-16 00:15:11 +00002741
Guido van Rossum18468821994-06-20 07:49:28 +00002742/**** Tkapp Method List ****/
2743
2744static PyMethodDef Tkapp_methods[] =
2745{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002746 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002747 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Neal Norwitze2e447b2007-05-22 07:16:10 +00002748 {"call", Tkapp_Call, METH_VARARGS},
2749 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002750 {"eval", Tkapp_Eval, METH_VARARGS},
2751 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2752 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2753 {"record", Tkapp_Record, METH_VARARGS},
2754 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2755 {"setvar", Tkapp_SetVar, METH_VARARGS},
2756 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2757 {"getvar", Tkapp_GetVar, METH_VARARGS},
2758 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2759 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2760 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2761 {"getint", Tkapp_GetInt, METH_VARARGS},
2762 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2763 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2764 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2765 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2766 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2767 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2768 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2769 {"split", Tkapp_Split, METH_VARARGS},
Neal Norwitze2e447b2007-05-22 07:16:10 +00002770 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002771 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2772 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002773#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002774 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2775 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002776#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002777 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2778 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2779 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2780 {"quit", Tkapp_Quit, METH_VARARGS},
2781 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002782 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002783 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002784};
2785
Barry Warsawfa701a81997-01-16 00:15:11 +00002786
2787
Guido van Rossum18468821994-06-20 07:49:28 +00002788/**** Tkapp Type Methods ****/
2789
2790static void
Fred Drake509d79a2000-07-08 04:04:38 +00002791Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002792{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002793 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002794 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002795 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002796 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002797 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002798 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002799}
2800
2801static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002802Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002803{
Guido van Rossum35d43371997-08-02 00:09:09 +00002804 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002805}
2806
2807static PyTypeObject Tkapp_Type =
2808{
Martin v. Löwis68192102007-07-21 06:55:02 +00002809 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002810 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002811 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002812 0, /*tp_itemsize */
2813 Tkapp_Dealloc, /*tp_dealloc */
2814 0, /*tp_print */
2815 Tkapp_GetAttr, /*tp_getattr */
2816 0, /*tp_setattr */
2817 0, /*tp_compare */
2818 0, /*tp_repr */
2819 0, /*tp_as_number */
2820 0, /*tp_as_sequence */
2821 0, /*tp_as_mapping */
2822 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002823};
2824
Barry Warsawfa701a81997-01-16 00:15:11 +00002825
2826
Guido van Rossum18468821994-06-20 07:49:28 +00002827/**** Tkinter Module ****/
2828
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002829typedef struct {
2830 PyObject* tuple;
2831 int size; /* current size */
2832 int maxsize; /* allocated size */
2833} FlattenContext;
2834
2835static int
2836_bump(FlattenContext* context, int size)
2837{
Guido van Rossum2834b972000-10-06 16:58:26 +00002838 /* expand tuple to hold (at least) size new items.
2839 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002840
2841 int maxsize = context->maxsize * 2;
2842
2843 if (maxsize < context->size + size)
2844 maxsize = context->size + size;
2845
2846 context->maxsize = maxsize;
2847
Tim Peters4324aa32001-05-28 22:30:08 +00002848 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002849}
2850
2851static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002852_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002853{
2854 /* add tuple or list to argument tuple (recursively) */
2855
2856 int i, size;
2857
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002858 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002859 PyErr_SetString(PyExc_ValueError,
2860 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002861 return 0;
2862 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002863 size = PyList_GET_SIZE(item);
2864 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002865 if (context->size + size > context->maxsize &&
2866 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002867 return 0;
2868 /* copy items to output tuple */
2869 for (i = 0; i < size; i++) {
2870 PyObject *o = PyList_GET_ITEM(item, i);
2871 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002872 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002873 return 0;
2874 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002875 if (context->size + 1 > context->maxsize &&
2876 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002877 return 0;
2878 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002879 PyTuple_SET_ITEM(context->tuple,
2880 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002881 }
2882 }
2883 } else if (PyTuple_Check(item)) {
2884 /* same, for tuples */
2885 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002886 if (context->size + size > context->maxsize &&
2887 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002888 return 0;
2889 for (i = 0; i < size; i++) {
2890 PyObject *o = PyTuple_GET_ITEM(item, i);
2891 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002892 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002893 return 0;
2894 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002895 if (context->size + 1 > context->maxsize &&
2896 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002897 return 0;
2898 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002899 PyTuple_SET_ITEM(context->tuple,
2900 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002901 }
2902 }
2903 } else {
2904 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2905 return 0;
2906 }
2907 return 1;
2908}
2909
2910static PyObject *
2911Tkinter_Flatten(PyObject* self, PyObject* args)
2912{
2913 FlattenContext context;
2914 PyObject* item;
2915
2916 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2917 return NULL;
2918
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002919 context.maxsize = PySequence_Size(item);
Benjamin Petersonb3619be2009-01-30 02:24:39 +00002920 if (context.maxsize < 0)
2921 return NULL;
2922 if (context.maxsize == 0)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002923 return PyTuple_New(0);
2924
2925 context.tuple = PyTuple_New(context.maxsize);
2926 if (!context.tuple)
2927 return NULL;
2928
2929 context.size = 0;
2930
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002931 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002932 return NULL;
2933
Tim Peters4324aa32001-05-28 22:30:08 +00002934 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002935 return NULL;
2936
2937 return context.tuple;
2938}
2939
Guido van Rossum18468821994-06-20 07:49:28 +00002940static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002941Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002942{
Barry Warsawfa701a81997-01-16 00:15:11 +00002943 char *screenName = NULL;
2944 char *baseName = NULL;
2945 char *className = NULL;
2946 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002947 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002948 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002949 int sync = 0; /* pass -sync to wish */
2950 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002951
Guido van Rossum35d43371997-08-02 00:09:09 +00002952 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002953 if (baseName != NULL)
2954 baseName++;
2955 else
2956 baseName = Py_GetProgramName();
2957 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002958
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002959 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002960 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002961 &interactive, &wantobjects, &wantTk,
2962 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00002963 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002964
Barry Warsawfa701a81997-01-16 00:15:11 +00002965 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002966 interactive, wantobjects, wantTk,
2967 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002968}
2969
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002970static PyObject *
2971Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2972{
2973 int new_val;
2974 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2975 return NULL;
2976 if (new_val < 0) {
2977 PyErr_SetString(PyExc_ValueError,
2978 "busywaitinterval must be >= 0");
2979 return NULL;
2980 }
2981 Tkinter_busywaitinterval = new_val;
2982 Py_INCREF(Py_None);
2983 return Py_None;
2984}
2985
2986static char setbusywaitinterval_doc[] =
2987"setbusywaitinterval(n) -> None\n\
2988\n\
2989Set the busy-wait interval in milliseconds between successive\n\
2990calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2991It should be set to a divisor of the maximum time between\n\
2992frames in an animation.";
2993
2994static PyObject *
2995Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2996{
2997 return PyInt_FromLong(Tkinter_busywaitinterval);
2998}
2999
3000static char getbusywaitinterval_doc[] =
3001"getbusywaitinterval() -> int\n\
3002\n\
3003Return the current busy-wait interval between successive\n\
3004calls to Tcl_DoOneEvent in a threaded Python interpreter.";
3005
Guido van Rossum18468821994-06-20 07:49:28 +00003006static PyMethodDef moduleMethods[] =
3007{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003008 {"_flatten", Tkinter_Flatten, METH_VARARGS},
3009 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00003010#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003011 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
3012 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00003013#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003014 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
3015 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
3016 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
3017 {"quit", Tkapp_Quit, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003018 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
3019 setbusywaitinterval_doc},
3020 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
3021 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00003022 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00003023};
3024
Guido van Rossum7bf15641998-05-22 18:28:17 +00003025#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003026
3027static int stdin_ready = 0;
3028
Guido van Rossumad4db171998-06-13 13:56:28 +00003029#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00003030static void
Fred Drake509d79a2000-07-08 04:04:38 +00003031MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003032{
3033 stdin_ready = 1;
3034}
Guido van Rossumad4db171998-06-13 13:56:28 +00003035#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003036
Martin v. Löwisa9656492003-03-30 08:44:58 +00003037#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003038static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00003039#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00003040
Guido van Rossum18468821994-06-20 07:49:28 +00003041static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003042EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003043{
Guido van Rossumad4db171998-06-13 13:56:28 +00003044#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00003045 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00003046#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003047#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003048 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003049#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003050 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00003051 errorInCmd = 0;
3052#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00003053 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003054 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00003055#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003056 while (!errorInCmd && !stdin_ready) {
3057 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00003058#ifdef MS_WINDOWS
3059 if (_kbhit()) {
3060 stdin_ready = 1;
3061 break;
3062 }
3063#endif
3064#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00003065 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003066 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00003067 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003068
Guido van Rossum00d93061998-05-28 23:06:38 +00003069 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003070
3071 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003072 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00003073 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003074 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00003075 Py_END_ALLOW_THREADS
3076#else
3077 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003078#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003079
3080 if (result < 0)
3081 break;
3082 }
Guido van Rossumad4db171998-06-13 13:56:28 +00003083#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00003084 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00003085#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003086 if (errorInCmd) {
3087 errorInCmd = 0;
3088 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3089 excInCmd = valInCmd = trbInCmd = NULL;
3090 PyErr_Print();
3091 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003092#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003093 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003094#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003095 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00003096}
Guido van Rossum18468821994-06-20 07:49:28 +00003097
Guido van Rossum00d93061998-05-28 23:06:38 +00003098#endif
3099
Guido van Rossum7bf15641998-05-22 18:28:17 +00003100static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003101EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003102{
Guido van Rossum00d93061998-05-28 23:06:38 +00003103#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003104 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003105#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003106 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003107#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003108 PyOS_InputHook = EventHook;
3109 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003110#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003111}
3112
3113static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003114DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003115{
Guido van Rossum00d93061998-05-28 23:06:38 +00003116#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003117 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3118 PyOS_InputHook = NULL;
3119 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003120#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003121}
3122
Barry Warsawfa701a81997-01-16 00:15:11 +00003123
3124/* all errors will be checked in one fell swoop in init_tkinter() */
3125static void
Fred Drake509d79a2000-07-08 04:04:38 +00003126ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003127{
3128 PyObject *v = PyInt_FromLong(val);
3129 if (v) {
3130 PyDict_SetItemString(d, name, v);
3131 Py_DECREF(v);
3132 }
3133}
3134static void
Fred Drake509d79a2000-07-08 04:04:38 +00003135ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003136{
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003137 PyObject *v = PyString_FromString(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003138 if (v) {
3139 PyDict_SetItemString(d, name, v);
3140 Py_DECREF(v);
3141 }
3142}
3143
3144
Mark Hammond62b1ab12002-07-23 06:31:15 +00003145PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003146init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003147{
Barry Warsawfa701a81997-01-16 00:15:11 +00003148 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00003149
Christian Heimese93237d2007-12-19 02:37:44 +00003150 Py_TYPE(&Tkapp_Type) = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00003151
3152#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003153 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003154#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003155
Barry Warsawfa701a81997-01-16 00:15:11 +00003156 m = Py_InitModule("_tkinter", moduleMethods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003157 if (m == NULL)
3158 return;
Guido van Rossum18468821994-06-20 07:49:28 +00003159
Barry Warsawfa701a81997-01-16 00:15:11 +00003160 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003161 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003162 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003163
Guido van Rossum35d43371997-08-02 00:09:09 +00003164 ins_long(d, "READABLE", TCL_READABLE);
3165 ins_long(d, "WRITABLE", TCL_WRITABLE);
3166 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3167 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3168 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3169 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3170 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3171 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3172 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003173 ins_string(d, "TK_VERSION", TK_VERSION);
3174 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003175
Guido van Rossum83551bf1997-09-13 00:44:23 +00003176 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003177
Christian Heimese93237d2007-12-19 02:37:44 +00003178 Py_TYPE(&Tktt_Type) = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003179 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3180
Christian Heimese93237d2007-12-19 02:37:44 +00003181 Py_TYPE(&PyTclObject_Type) = &PyType_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003182 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003183
3184#ifdef TK_AQUA
3185 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3186 * start waking up. Note that Tcl_FindExecutable will do this, this
3187 * code must be above it! The original warning from
3188 * tkMacOSXAppInit.c is copied below.
3189 *
3190 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3191 * Tcl interpreter for now. It probably should work to do this
3192 * in the other order, but for now it doesn't seem to.
3193 *
3194 */
3195 Tk_MacOSXSetupTkNotifier();
3196#endif
3197
3198
Guido van Rossume187b0e2000-03-27 21:46:29 +00003199 /* This helps the dynamic loader; in Unicode aware Tcl versions
3200 it also helps Tcl find its encodings. */
3201 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00003202
Barry Warsawfa701a81997-01-16 00:15:11 +00003203 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003204 return;
3205
Guido van Rossum43ff8681998-07-14 18:02:13 +00003206#if 0
3207 /* This was not a good idea; through <Destroy> bindings,
3208 Tcl_Finalize() may invoke Python code but at that point the
3209 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003210 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003211#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003212
Guido van Rossum18468821994-06-20 07:49:28 +00003213}