blob: 4056bcd412e4d66516f13f607d1fbcbca5ac813f [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
Guilherme Poloa66cf5b2009-02-09 20:50:27 +000036#include "tkinter.h"
37
Martin v. Löwis39195712003-01-04 00:33:13 +000038/* Allow using this code in Python 2.[12] */
39#ifndef PyDoc_STRVAR
Martin v. Löwiscd9a8b62003-01-21 21:52:57 +000040#define PyDoc_STRVAR(name,str) static char name[] = str
Martin v. Löwis39195712003-01-04 00:33:13 +000041#endif
42
43#ifndef PyMODINIT_FUNC
Martin v. Löwis3a57d9d2003-01-04 08:54:59 +000044#define PyMODINIT_FUNC void
Martin v. Löwis39195712003-01-04 00:33:13 +000045#endif
46
Martin v. Löwis52ae6f62003-03-30 08:26:04 +000047#ifndef PyBool_Check
48#define PyBool_Check(o) 0
49#define PyBool_FromLong PyInt_FromLong
50#endif
51
Martin v. Löwis71e25a02002-10-01 18:08:06 +000052/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
53 making _tkinter correct for this API means to break earlier
54 versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
55 earlier versions. Once Tcl releases before 8.4 don't need to be supported
56 anymore, this should go. */
57#define USE_COMPAT_CONST
58
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000059/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
60 it always; if Tcl is not threaded, the thread functions in
61 Tcl are empty. */
62#define TCL_THREADS
63
Jack Jansencb852442001-12-09 23:15:56 +000064#ifdef TK_FRAMEWORK
65#include <Tcl/tcl.h>
66#include <Tk/tk.h>
67#else
Guido van Rossum18468821994-06-20 07:49:28 +000068#include <tcl.h>
69#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000070#endif
Guido van Rossum18468821994-06-20 07:49:28 +000071
Jason Tishlerbbe89612002-12-31 20:30:46 +000072/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
Martin v. Löwis5b177f12002-12-30 18:14:15 +000073#ifndef CONST84_RETURN
74#define CONST84_RETURN
Jason Tishlerbbe89612002-12-31 20:30:46 +000075#undef CONST
Martin v. Löwis5b177f12002-12-30 18:14:15 +000076#define CONST
77#endif
78
Guilherme Poloc5eba1e2009-02-09 20:57:45 +000079#if TK_VERSION_HEX < 0x08030102
80#error "Tk older than 8.3.1 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
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000283#ifdef TKINTER_PROTECT_LOADTK
284static int tk_load_failed;
285#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000286
287
Guido van Rossum18468821994-06-20 07:49:28 +0000288static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000289Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000290{
Barry Warsawfa701a81997-01-16 00:15:11 +0000291 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
292 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000293}
294
Barry Warsawfa701a81997-01-16 00:15:11 +0000295
Barry Warsawfa701a81997-01-16 00:15:11 +0000296
Guido van Rossum18468821994-06-20 07:49:28 +0000297/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000298
Martin v. Löwis28e9ce92003-05-09 08:19:48 +0000299static int Tkinter_busywaitinterval = 20;
300
Guido van Rossum00d93061998-05-28 23:06:38 +0000301#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000302#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000303
Guido van Rossum00d93061998-05-28 23:06:38 +0000304/* Millisecond sleep() for Unix platforms. */
305
306static void
Fred Drake509d79a2000-07-08 04:04:38 +0000307Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000308{
309 /* XXX Too bad if you don't have select(). */
310 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000311 t.tv_sec = milli/1000;
312 t.tv_usec = (milli%1000) * 1000;
313 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
314}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000315#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000316
Martin v. Löwis5b26abb2002-12-28 09:23:09 +0000317/* Wait up to 1s for the mainloop to come up. */
318
319static int
320WaitForMainloop(TkappObject* self)
321{
322 int i;
323 for (i = 0; i < 10; i++) {
324 if (self->dispatching)
325 return 1;
326 Py_BEGIN_ALLOW_THREADS
327 Sleep(100);
328 Py_END_ALLOW_THREADS
329 }
330 if (self->dispatching)
331 return 1;
332 PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
333 return 0;
334}
Martin v. Löwisa9656492003-03-30 08:44:58 +0000335#endif /* WITH_THREAD */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000336
Guido van Rossum00d93061998-05-28 23:06:38 +0000337
Guido van Rossum18468821994-06-20 07:49:28 +0000338static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000339AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000340{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000341 if (PyString_Check(value))
342 return PyString_AsString(value);
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000343#ifdef Py_USING_UNICODE
Guido van Rossum2834b972000-10-06 16:58:26 +0000344 else if (PyUnicode_Check(value)) {
345 PyObject *v = PyUnicode_AsUTF8String(value);
346 if (v == NULL)
347 return NULL;
348 if (PyList_Append(tmp, v) != 0) {
349 Py_DECREF(v);
350 return NULL;
351 }
352 Py_DECREF(v);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000353 return PyString_AsString(v);
Guido van Rossum2834b972000-10-06 16:58:26 +0000354 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000355#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000356 else {
357 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000358 if (v == NULL)
359 return NULL;
360 if (PyList_Append(tmp, v) != 0) {
361 Py_DECREF(v);
362 return NULL;
363 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000364 Py_DECREF(v);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000365 return PyString_AsString(v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000366 }
Guido van Rossum18468821994-06-20 07:49:28 +0000367}
368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369
370
Guido van Rossum18468821994-06-20 07:49:28 +0000371#define ARGSZ 64
372
373static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000374Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000375{
Barry Warsawfa701a81997-01-16 00:15:11 +0000376 PyObject *tmp = NULL;
377 char *argvStore[ARGSZ];
378 char **argv = NULL;
379 int fvStore[ARGSZ];
380 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000381 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000382 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 if (!(tmp = PyList_New(0)))
385 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000386
Barry Warsawfa701a81997-01-16 00:15:11 +0000387 argv = argvStore;
388 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000389
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 if (args == NULL)
391 argc = 0;
392
393 else if (!PyTuple_Check(args)) {
394 argc = 1;
395 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000396 if (!(argv[0] = AsString(args, tmp)))
397 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000398 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000399 else {
400 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000401
Barry Warsawfa701a81997-01-16 00:15:11 +0000402 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000403 argv = (char **)ckalloc(argc * sizeof(char *));
404 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000405 if (argv == NULL || fv == NULL) {
406 PyErr_NoMemory();
407 goto finally;
408 }
409 }
410
411 for (i = 0; i < argc; i++) {
412 PyObject *v = PyTuple_GetItem(args, i);
413 if (PyTuple_Check(v)) {
414 fv[i] = 1;
415 if (!(argv[i] = Merge(v)))
416 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000417 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000418 }
419 else if (v == Py_None) {
420 argc = i;
421 break;
422 }
423 else {
424 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000425 if (!(argv[i] = AsString(v, tmp)))
426 goto finally;
427 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 }
429 }
Guido van Rossum18468821994-06-20 07:49:28 +0000430 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000432 if (res == NULL)
433 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000434
Barry Warsawfa701a81997-01-16 00:15:11 +0000435 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000436 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000437 if (fv[i]) {
438 ckfree(argv[i]);
439 }
440 if (argv != argvStore)
441 ckfree(FREECAST argv);
442 if (fv != fvStore)
443 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000444
Barry Warsawfa701a81997-01-16 00:15:11 +0000445 Py_DECREF(tmp);
446 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000447}
448
Barry Warsawfa701a81997-01-16 00:15:11 +0000449
450
Guido van Rossum18468821994-06-20 07:49:28 +0000451static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000452Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000453{
Barry Warsawfa701a81997-01-16 00:15:11 +0000454 int argc;
455 char **argv;
456 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000457
Barry Warsawfa701a81997-01-16 00:15:11 +0000458 if (list == NULL) {
459 Py_INCREF(Py_None);
460 return Py_None;
461 }
Guido van Rossum18468821994-06-20 07:49:28 +0000462
Guido van Rossum00d93061998-05-28 23:06:38 +0000463 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000464 /* Not a list.
465 * Could be a quoted string containing funnies, e.g. {"}.
466 * Return the string itself.
467 */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000468 return PyString_FromString(list);
Barry Warsawfa701a81997-01-16 00:15:11 +0000469 }
Guido van Rossum18468821994-06-20 07:49:28 +0000470
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 if (argc == 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000472 v = PyString_FromString("");
Barry Warsawfa701a81997-01-16 00:15:11 +0000473 else if (argc == 1)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000474 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000475 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 int i;
477 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000478
Barry Warsawfa701a81997-01-16 00:15:11 +0000479 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000480 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000481 Py_DECREF(v);
482 v = NULL;
483 break;
484 }
485 PyTuple_SetItem(v, i, w);
486 }
487 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000488 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000489 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000490}
491
Martin v. Löwisffad6332002-11-26 09:28:05 +0000492/* In some cases, Tcl will still return strings that are supposed to be
493 lists. SplitObj walks through a nested tuple, finding string objects that
494 need to be split. */
495
Martin v. Löwis111c1802008-06-13 07:47:47 +0000496static PyObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000497SplitObj(PyObject *arg)
498{
499 if (PyTuple_Check(arg)) {
500 int i, size;
501 PyObject *elem, *newelem, *result;
502
503 size = PyTuple_Size(arg);
504 result = NULL;
505 /* Recursively invoke SplitObj for all tuple items.
506 If this does not return a new object, no action is
507 needed. */
508 for(i = 0; i < size; i++) {
509 elem = PyTuple_GetItem(arg, i);
510 newelem = SplitObj(elem);
511 if (!newelem) {
512 Py_XDECREF(result);
513 return NULL;
514 }
515 if (!result) {
516 int k;
517 if (newelem == elem) {
518 Py_DECREF(newelem);
519 continue;
520 }
521 result = PyTuple_New(size);
522 if (!result)
523 return NULL;
524 for(k = 0; k < i; k++) {
525 elem = PyTuple_GetItem(arg, k);
526 Py_INCREF(elem);
527 PyTuple_SetItem(result, k, elem);
528 }
529 }
530 PyTuple_SetItem(result, i, newelem);
531 }
532 if (result)
533 return result;
534 /* Fall through, returning arg. */
535 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000536 else if (PyString_Check(arg)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000537 int argc;
538 char **argv;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000539 char *list = PyString_AsString(arg);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000540
541 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
542 Py_INCREF(arg);
543 return arg;
544 }
545 Tcl_Free(FREECAST argv);
546 if (argc > 1)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000547 return Split(PyString_AsString(arg));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000548 /* Fall through, returning arg. */
549 }
550 Py_INCREF(arg);
551 return arg;
552}
Barry Warsawfa701a81997-01-16 00:15:11 +0000553
554
Guido van Rossum18468821994-06-20 07:49:28 +0000555/**** Tkapp Object ****/
556
557#ifndef WITH_APPINIT
558int
Fred Drake509d79a2000-07-08 04:04:38 +0000559Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000560{
David Aschere2b4b322004-02-18 05:59:53 +0000561 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000562
Barry Warsawfa701a81997-01-16 00:15:11 +0000563 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000564 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000565 return TCL_ERROR;
566 }
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000567
568 _tkinter_skip_tk_init = Tcl_GetVar(interp,
569 "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
570 if (_tkinter_skip_tk_init != NULL &&
571 strcmp(_tkinter_skip_tk_init, "1") == 0) {
572 return TCL_OK;
Barry Warsawfa701a81997-01-16 00:15:11 +0000573 }
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000574
575#ifdef TKINTER_PROTECT_LOADTK
576 if (tk_load_failed) {
577 PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG);
578 return TCL_ERROR;
579 }
580#endif
581
582 if (Tk_Init(interp) == TCL_ERROR) {
583#ifdef TKINTER_PROTECT_LOADTK
584 tk_load_failed = 1;
585#endif
586 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
587 return TCL_ERROR;
588 }
589
Barry Warsawfa701a81997-01-16 00:15:11 +0000590 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000591}
592#endif /* !WITH_APPINIT */
593
Guido van Rossum18468821994-06-20 07:49:28 +0000594
Barry Warsawfa701a81997-01-16 00:15:11 +0000595
596
597/* Initialize the Tk application; see the `main' function in
598 * `tkMain.c'.
599 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000600
Thomas Wouters58d05102000-07-24 14:43:35 +0000601static void EnableEventHook(void); /* Forward */
602static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000603
Barry Warsawfa701a81997-01-16 00:15:11 +0000604static TkappObject *
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000605Tkapp_New(char *screenName, char *baseName, char *className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000606 int interactive, int wantobjects, int wantTk, int sync, char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000607{
608 TkappObject *v;
609 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000610
Guido van Rossumb18618d2000-05-03 23:44:39 +0000611 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000612 if (v == NULL)
613 return NULL;
614
615 v->interp = Tcl_CreateInterp();
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000616 v->wantobjects = wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000617 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
618 TCL_GLOBAL_ONLY) != NULL;
619 v->thread_id = Tcl_GetCurrentThread();
620 v->dispatching = 0;
621
622#ifndef TCL_THREADS
623 if (v->threaded) {
624 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
625 Py_DECREF(v);
626 return 0;
627 }
628#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000629#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000630 if (v->threaded && tcl_lock) {
631 /* If Tcl is threaded, we don't need the lock. */
632 PyThread_free_lock(tcl_lock);
633 tcl_lock = NULL;
634 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000635#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000636
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000637 v->BooleanType = Tcl_GetObjType("boolean");
638 v->ByteArrayType = Tcl_GetObjType("bytearray");
639 v->DoubleType = Tcl_GetObjType("double");
640 v->IntType = Tcl_GetObjType("int");
641 v->ListType = Tcl_GetObjType("list");
642 v->ProcBodyType = Tcl_GetObjType("procbody");
643 v->StringType = Tcl_GetObjType("string");
644
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000645 /* Delete the 'exit' command, which can screw things up */
646 Tcl_DeleteCommand(v->interp, "exit");
647
Barry Warsawfa701a81997-01-16 00:15:11 +0000648 if (screenName != NULL)
649 Tcl_SetVar2(v->interp, "env", "DISPLAY",
650 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000651
Barry Warsawfa701a81997-01-16 00:15:11 +0000652 if (interactive)
653 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
654 else
655 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000656
Barry Warsawfa701a81997-01-16 00:15:11 +0000657 /* This is used to get the application class for Tk 4.1 and up */
658 argv0 = (char*)ckalloc(strlen(className) + 1);
659 if (!argv0) {
660 PyErr_NoMemory();
661 Py_DECREF(v);
662 return NULL;
663 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000664
Barry Warsawfa701a81997-01-16 00:15:11 +0000665 strcpy(argv0, className);
Neal Norwitz9dbc7dd2005-12-19 06:08:59 +0000666 if (isupper(Py_CHARMASK(argv0[0])))
Neal Norwitz65c05b22006-04-10 02:17:47 +0000667 argv0[0] = tolower(Py_CHARMASK(argv0[0]));
Barry Warsawfa701a81997-01-16 00:15:11 +0000668 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
669 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000670
David Aschere2b4b322004-02-18 05:59:53 +0000671 if (! wantTk) {
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000672 Tcl_SetVar(v->interp,
673 "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
David Aschere2b4b322004-02-18 05:59:53 +0000674 }
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000675#ifdef TKINTER_PROTECT_LOADTK
676 else if (tk_load_failed) {
677 Tcl_SetVar(v->interp,
678 "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY);
679 }
680#endif
David Aschere2b4b322004-02-18 05:59:53 +0000681
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000682 /* some initial arguments need to be in argv */
683 if (sync || use) {
Tim Peters51fa3b72004-08-04 02:16:48 +0000684 char *args;
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000685 int len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000686
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000687 if (sync)
688 len += sizeof "-sync";
689 if (use)
690 len += strlen(use) + sizeof "-use ";
691
Tim Peters51fa3b72004-08-04 02:16:48 +0000692 args = (char*)ckalloc(len);
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000693 if (!args) {
694 PyErr_NoMemory();
695 Py_DECREF(v);
696 return NULL;
697 }
698
699 args[0] = '\0';
700 if (sync)
701 strcat(args, "-sync");
702 if (use) {
703 if (sync)
704 strcat(args, " ");
705 strcat(args, "-use ");
706 strcat(args, use);
707 }
708
709 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
710 ckfree(args);
711 }
712
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000713 if (Tcl_AppInit(v->interp) != TCL_OK) {
714 PyObject *result = Tkinter_Error((PyObject *)v);
Guilherme Poloa66cf5b2009-02-09 20:50:27 +0000715#ifdef TKINTER_PROTECT_LOADTK
716 if (wantTk) {
717 const char *_tkinter_tk_failed;
718 _tkinter_tk_failed = Tcl_GetVar(v->interp,
719 "_tkinter_tk_failed", TCL_GLOBAL_ONLY);
720
721 if ( _tkinter_tk_failed != NULL &&
722 strcmp(_tkinter_tk_failed, "1") == 0) {
723 tk_load_failed = 1;
724 }
725 }
726#endif
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000727 Py_DECREF((PyObject *)v);
728 return (TkappObject *)result;
729 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000730
Guido van Rossum7bf15641998-05-22 18:28:17 +0000731 EnableEventHook();
732
Barry Warsawfa701a81997-01-16 00:15:11 +0000733 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000734}
735
Barry Warsawfa701a81997-01-16 00:15:11 +0000736
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000737static void
738Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
739 Tcl_Condition *cond, Tcl_Mutex *mutex)
740{
741 Py_BEGIN_ALLOW_THREADS;
742 Tcl_MutexLock(mutex);
743 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
744 Tcl_ThreadAlert(self->thread_id);
745 Tcl_ConditionWait(cond, mutex, NULL);
746 Tcl_MutexUnlock(mutex);
747 Py_END_ALLOW_THREADS
748}
749
Barry Warsawfa701a81997-01-16 00:15:11 +0000750
Guido van Rossum18468821994-06-20 07:49:28 +0000751/** Tcl Eval **/
752
Martin v. Löwisffad6332002-11-26 09:28:05 +0000753typedef struct {
754 PyObject_HEAD
755 Tcl_Obj *value;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000756 PyObject *string; /* This cannot cause cycles. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000757} PyTclObject;
758
759staticforward PyTypeObject PyTclObject_Type;
760#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
761
762static PyObject *
763newPyTclObject(Tcl_Obj *arg)
764{
765 PyTclObject *self;
766 self = PyObject_New(PyTclObject, &PyTclObject_Type);
767 if (self == NULL)
768 return NULL;
769 Tcl_IncrRefCount(arg);
770 self->value = arg;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000771 self->string = NULL;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000772 return (PyObject*)self;
773}
774
775static void
776PyTclObject_dealloc(PyTclObject *self)
777{
778 Tcl_DecrRefCount(self->value);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000779 Py_XDECREF(self->string);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000780 PyObject_Del(self);
781}
782
783static PyObject *
784PyTclObject_str(PyTclObject *self)
785{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000786 if (self->string && PyString_Check(self->string)) {
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000787 Py_INCREF(self->string);
788 return self->string;
789 }
790 /* XXX Could cache value if it is an ASCII string. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000791 return PyString_FromString(Tcl_GetString(self->value));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000792}
793
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000794static char*
795PyTclObject_TclString(PyObject *self)
796{
797 return Tcl_GetString(((PyTclObject*)self)->value);
798}
799
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000800/* Like _str, but create Unicode if necessary. */
Martin v. Löwis39195712003-01-04 00:33:13 +0000801PyDoc_STRVAR(PyTclObject_string__doc__,
802"the string representation of this object, either as string or Unicode");
803
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000804static PyObject *
805PyTclObject_string(PyTclObject *self, void *ignored)
806{
807 char *s;
808 int i, len;
809 if (!self->string) {
810 s = Tcl_GetStringFromObj(self->value, &len);
811 for (i = 0; i < len; i++)
812 if (s[i] & 0x80)
813 break;
814#ifdef Py_USING_UNICODE
815 if (i == len)
816 /* It is an ASCII string. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000817 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000818 else {
819 self->string = PyUnicode_DecodeUTF8(s, len, "strict");
820 if (!self->string) {
821 PyErr_Clear();
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000822 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000823 }
824 }
825#else
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000826 self->string = PyString_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000827#endif
828 if (!self->string)
829 return NULL;
830 }
831 Py_INCREF(self->string);
832 return self->string;
833}
834
835#ifdef Py_USING_UNICODE
Martin v. Löwis39195712003-01-04 00:33:13 +0000836PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode");
837
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000838static PyObject *
839PyTclObject_unicode(PyTclObject *self, void *ignored)
840{
841 char *s;
842 int len;
843 if (self->string && PyUnicode_Check(self->string)) {
844 Py_INCREF(self->string);
845 return self->string;
846 }
847 /* XXX Could chache result if it is non-ASCII. */
848 s = Tcl_GetStringFromObj(self->value, &len);
849 return PyUnicode_DecodeUTF8(s, len, "strict");
850}
851#endif
852
Martin v. Löwisffad6332002-11-26 09:28:05 +0000853static PyObject *
854PyTclObject_repr(PyTclObject *self)
855{
856 char buf[50];
Martin v. Löwisfba73692004-11-13 11:13:35 +0000857 PyOS_snprintf(buf, 50, "<%s object at %p>",
858 self->value->typePtr->name, self->value);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000859 return PyString_FromString(buf);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000860}
861
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000862static int
863PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
864{
865 int res;
866 res = strcmp(Tcl_GetString(self->value),
867 Tcl_GetString(other->value));
868 if (res < 0) return -1;
869 if (res > 0) return 1;
870 return 0;
871}
872
Martin v. Löwis39195712003-01-04 00:33:13 +0000873PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
874
Martin v. Löwisffad6332002-11-26 09:28:05 +0000875static PyObject*
876get_typename(PyTclObject* obj, void* ignored)
877{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000878 return PyString_FromString(obj->value->typePtr->name);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000879}
880
Martin v. Löwis39195712003-01-04 00:33:13 +0000881
Martin v. Löwisffad6332002-11-26 09:28:05 +0000882static PyGetSetDef PyTclObject_getsetlist[] = {
Martin v. Löwis39195712003-01-04 00:33:13 +0000883 {"typename", (getter)get_typename, NULL, get_typename__doc__},
884 {"string", (getter)PyTclObject_string, NULL,
885 PyTclObject_string__doc__},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000886 {0},
887};
888
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000889static PyMethodDef PyTclObject_methods[] = {
Martin v. Löwise2713be2005-03-08 15:03:08 +0000890#ifdef Py_USING_UNICODE
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000891 {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS,
Martin v. Löwis39195712003-01-04 00:33:13 +0000892 PyTclObject_unicode__doc__},
Martin v. Löwise2713be2005-03-08 15:03:08 +0000893#endif
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000894 {0}
895};
896
Martin v. Löwisffad6332002-11-26 09:28:05 +0000897statichere PyTypeObject PyTclObject_Type = {
898 PyObject_HEAD_INIT(NULL)
899 0, /*ob_size*/
900 "_tkinter.Tcl_Obj", /*tp_name*/
901 sizeof(PyTclObject), /*tp_basicsize*/
902 0, /*tp_itemsize*/
903 /* methods */
904 (destructor)PyTclObject_dealloc, /*tp_dealloc*/
905 0, /*tp_print*/
906 0, /*tp_getattr*/
907 0, /*tp_setattr*/
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000908 (cmpfunc)PyTclObject_cmp, /*tp_compare*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000909 (reprfunc)PyTclObject_repr, /*tp_repr*/
910 0, /*tp_as_number*/
911 0, /*tp_as_sequence*/
912 0, /*tp_as_mapping*/
913 0, /*tp_hash*/
914 0, /*tp_call*/
915 (reprfunc)PyTclObject_str, /*tp_str*/
Jason Tishlerfb8595d2003-01-06 12:41:26 +0000916 PyObject_GenericGetAttr,/*tp_getattro*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000917 0, /*tp_setattro*/
918 0, /*tp_as_buffer*/
919 Py_TPFLAGS_DEFAULT, /*tp_flags*/
920 0, /*tp_doc*/
921 0, /*tp_traverse*/
922 0, /*tp_clear*/
923 0, /*tp_richcompare*/
924 0, /*tp_weaklistoffset*/
925 0, /*tp_iter*/
926 0, /*tp_iternext*/
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000927 PyTclObject_methods, /*tp_methods*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000928 0, /*tp_members*/
929 PyTclObject_getsetlist, /*tp_getset*/
930 0, /*tp_base*/
931 0, /*tp_dict*/
932 0, /*tp_descr_get*/
933 0, /*tp_descr_set*/
934 0, /*tp_dictoffset*/
935 0, /*tp_init*/
936 0, /*tp_alloc*/
937 0, /*tp_new*/
938 0, /*tp_free*/
939 0, /*tp_is_gc*/
940};
941
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000942static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000943AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000944{
945 Tcl_Obj *result;
946
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000947 if (PyString_Check(value))
948 return Tcl_NewStringObj(PyString_AS_STRING(value),
949 PyString_GET_SIZE(value));
Martin v. Löwis70c3dda2003-01-22 09:17:38 +0000950 else if (PyBool_Check(value))
951 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000952 else if (PyInt_Check(value))
953 return Tcl_NewLongObj(PyInt_AS_LONG(value));
954 else if (PyFloat_Check(value))
955 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
956 else if (PyTuple_Check(value)) {
957 Tcl_Obj **argv = (Tcl_Obj**)
958 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
959 int i;
960 if(!argv)
961 return 0;
962 for(i=0;i<PyTuple_Size(value);i++)
963 argv[i] = AsObj(PyTuple_GetItem(value,i));
964 result = Tcl_NewListObj(PyTuple_Size(value), argv);
965 ckfree(FREECAST argv);
966 return result;
967 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000968#ifdef Py_USING_UNICODE
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000969 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000970 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
Neal Norwitz047f3c72006-06-12 02:06:42 +0000971 Py_ssize_t size = PyUnicode_GET_SIZE(value);
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000972 /* This #ifdef assumes that Tcl uses UCS-2.
973 See TCL_UTF_MAX test above. */
Martin v. Löwis6f29ff32003-04-16 20:34:55 +0000974#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
Guido van Rossum076d9ee2008-01-03 23:54:04 +0000975 Tcl_UniChar *outbuf = NULL;
Neal Norwitz047f3c72006-06-12 02:06:42 +0000976 Py_ssize_t i;
Guido van Rossum076d9ee2008-01-03 23:54:04 +0000977 size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
978 if (allocsize >= size)
979 outbuf = (Tcl_UniChar*)ckalloc(allocsize);
980 /* Else overflow occurred, and we take the next exit */
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000981 if (!outbuf) {
982 PyErr_NoMemory();
983 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000984 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000985 for (i = 0; i < size; i++) {
986 if (inbuf[i] >= 0x10000) {
987 /* Tcl doesn't do UTF-16, yet. */
988 PyErr_SetString(PyExc_ValueError,
989 "unsupported character");
990 ckfree(FREECAST outbuf);
991 return NULL;
992 }
993 outbuf[i] = inbuf[i];
994 }
995 result = Tcl_NewUnicodeObj(outbuf, size);
996 ckfree(FREECAST outbuf);
997 return result;
998#else
999 return Tcl_NewUnicodeObj(inbuf, size);
1000#endif
1001
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001002 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001003#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +00001004 else if(PyTclObject_Check(value)) {
1005 Tcl_Obj *v = ((PyTclObject*)value)->value;
1006 Tcl_IncrRefCount(v);
1007 return v;
1008 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001009 else {
1010 PyObject *v = PyObject_Str(value);
1011 if (!v)
1012 return 0;
1013 result = AsObj(v);
1014 Py_DECREF(v);
1015 return result;
1016 }
1017}
1018
Martin v. Löwisffad6332002-11-26 09:28:05 +00001019static PyObject*
1020FromObj(PyObject* tkapp, Tcl_Obj *value)
1021{
1022 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001023 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +00001024
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001025 if (value->typePtr == NULL) {
1026 /* If the result contains any bytes with the top bit set,
1027 it's UTF-8 and we should decode it to Unicode */
1028#ifdef Py_USING_UNICODE
1029 int i;
1030 char *s = value->bytes;
1031 int len = value->length;
1032 for (i = 0; i < len; i++) {
1033 if (value->bytes[i] & 0x80)
1034 break;
1035 }
1036
1037 if (i == value->length)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001038 result = PyString_FromStringAndSize(s, len);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001039 else {
1040 /* Convert UTF-8 to Unicode string */
1041 result = PyUnicode_DecodeUTF8(s, len, "strict");
1042 if (result == NULL) {
1043 PyErr_Clear();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001044 result = PyString_FromStringAndSize(s, len);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001045 }
1046 }
1047#else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001048 result = PyString_FromStringAndSize(value->bytes, value->length);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001049#endif
1050 return result;
1051 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001052
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001053 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001054 result = value->internalRep.longValue ? Py_True : Py_False;
1055 Py_INCREF(result);
1056 return result;
1057 }
1058
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001059 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001060 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +00001061 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001062 return PyString_FromStringAndSize(data, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001063 }
1064
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001065 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001066 return PyFloat_FromDouble(value->internalRep.doubleValue);
1067 }
1068
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001069 if (value->typePtr == app->IntType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001070 return PyInt_FromLong(value->internalRep.longValue);
1071 }
1072
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001073 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001074 int size;
1075 int i, status;
1076 PyObject *elem;
1077 Tcl_Obj *tcl_elem;
1078
1079 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
1080 if (status == TCL_ERROR)
1081 return Tkinter_Error(tkapp);
1082 result = PyTuple_New(size);
1083 if (!result)
1084 return NULL;
1085 for (i = 0; i < size; i++) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001086 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
Martin v. Löwisffad6332002-11-26 09:28:05 +00001087 value, i, &tcl_elem);
1088 if (status == TCL_ERROR) {
1089 Py_DECREF(result);
1090 return Tkinter_Error(tkapp);
1091 }
1092 elem = FromObj(tkapp, tcl_elem);
1093 if (!elem) {
1094 Py_DECREF(result);
1095 return NULL;
1096 }
1097 PyTuple_SetItem(result, i, elem);
1098 }
1099 return result;
1100 }
1101
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001102 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001103 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +00001104 }
1105
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001106 if (value->typePtr == app->StringType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001107#ifdef Py_USING_UNICODE
Martin v. Löwis6f29ff32003-04-16 20:34:55 +00001108#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
Martin v. Löwisffad6332002-11-26 09:28:05 +00001109 PyObject *result;
1110 int size;
1111 Tcl_UniChar *input;
1112 Py_UNICODE *output;
1113
1114 size = Tcl_GetCharLength(value);
1115 result = PyUnicode_FromUnicode(NULL, size);
1116 if (!result)
1117 return NULL;
1118 input = Tcl_GetUnicode(value);
1119 output = PyUnicode_AS_UNICODE(result);
1120 while (size--)
1121 *output++ = *input++;
1122 return result;
1123#else
1124 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1125 Tcl_GetCharLength(value));
1126#endif
1127#else
1128 int size;
1129 char *c;
1130 c = Tcl_GetStringFromObj(value, &size);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001131 return PyString_FromStringAndSize(c, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001132#endif
1133 }
1134
1135 return newPyTclObject(value);
1136}
1137
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001138/* This mutex synchronizes inter-thread command calls. */
1139
1140TCL_DECLARE_MUTEX(call_mutex)
1141
1142typedef struct Tkapp_CallEvent {
1143 Tcl_Event ev; /* Must be first */
1144 TkappObject *self;
1145 PyObject *args;
1146 int flags;
1147 PyObject **res;
1148 PyObject **exc_type, **exc_value, **exc_tb;
Guilherme Polo363161a2009-02-06 22:48:07 +00001149 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001150} Tkapp_CallEvent;
1151
1152void
1153Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001154{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001155 int i;
1156 for (i = 0; i < objc; i++)
1157 Tcl_DecrRefCount(objv[i]);
1158 if (objv != objStore)
1159 ckfree(FREECAST objv);
1160}
Guido van Rossum18468821994-06-20 07:49:28 +00001161
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001162/* Convert Python objects to Tcl objects. This must happen in the
1163 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001164
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001165static Tcl_Obj**
1166Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1167{
1168 Tcl_Obj **objv = objStore;
Martin v. Löwis7d134952002-12-12 19:05:48 +00001169 int objc = 0, i;
Guido van Rossum212643f1998-04-29 16:22:14 +00001170 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +00001171 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001172
Guido van Rossum212643f1998-04-29 16:22:14 +00001173 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +00001174 objv[0] = AsObj(args);
1175 if (objv[0] == 0)
1176 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001177 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +00001178 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001179 }
1180 else {
Guido van Rossum632de272000-03-29 00:19:50 +00001181 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001182
Guido van Rossum632de272000-03-29 00:19:50 +00001183 if (objc > ARGSZ) {
1184 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1185 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001186 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +00001187 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +00001188 goto finally;
1189 }
1190 }
1191
Guido van Rossum632de272000-03-29 00:19:50 +00001192 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001193 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +00001194 if (v == Py_None) {
1195 objc = i;
1196 break;
1197 }
Guido van Rossum632de272000-03-29 00:19:50 +00001198 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +00001199 if (!objv[i]) {
1200 /* Reset objc, so it attempts to clear
1201 objects only up to i. */
1202 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +00001203 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001204 }
Guido van Rossum632de272000-03-29 00:19:50 +00001205 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001206 }
1207 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001208 *pobjc = objc;
1209 return objv;
1210finally:
1211 Tkapp_CallDeallocArgs(objv, objStore, objc);
1212 return NULL;
1213}
Guido van Rossum212643f1998-04-29 16:22:14 +00001214
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001215/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001216
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001217static PyObject*
1218Tkapp_CallResult(TkappObject *self)
1219{
1220 PyObject *res = NULL;
1221 if(self->wantobjects) {
1222 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001223 /* Not sure whether the IncrRef is necessary, but something
1224 may overwrite the interpreter result while we are
1225 converting it. */
1226 Tcl_IncrRefCount(value);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001227 res = FromObj((PyObject*)self, value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001228 Tcl_DecrRefCount(value);
1229 } else {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001230 const char *s = Tcl_GetStringResult(self->interp);
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001231 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001232
Guido van Rossum990f5c62000-05-04 15:07:16 +00001233 /* If the result contains any bytes with the top bit set,
1234 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001235#ifdef Py_USING_UNICODE
Guido van Rossum990f5c62000-05-04 15:07:16 +00001236 while (*p != '\0') {
1237 if (*p & 0x80)
1238 break;
1239 p++;
1240 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001241
Guido van Rossum990f5c62000-05-04 15:07:16 +00001242 if (*p == '\0')
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001243 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum990f5c62000-05-04 15:07:16 +00001244 else {
1245 /* Convert UTF-8 to Unicode string */
1246 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +00001247 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
1248 if (res == NULL) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001249 PyErr_Clear();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001250 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +00001251 }
Guido van Rossum990f5c62000-05-04 15:07:16 +00001252 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001253#else
1254 p = strchr(p, '\0');
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001255 res = PyString_FromStringAndSize(s, (int)(p-s));
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001256#endif
Guido van Rossum990f5c62000-05-04 15:07:16 +00001257 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001258 return res;
1259}
Guido van Rossum632de272000-03-29 00:19:50 +00001260
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001261/* Tkapp_CallProc is the event procedure that is executed in the context of
1262 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1263 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001264
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001265static int
1266Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1267{
1268 Tcl_Obj *objStore[ARGSZ];
1269 Tcl_Obj **objv;
1270 int objc;
1271 int i;
1272 ENTER_PYTHON
1273 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1274 if (!objv) {
1275 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1276 *(e->res) = NULL;
1277 }
1278 LEAVE_PYTHON
1279 if (!objv)
1280 goto done;
1281 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1282 ENTER_PYTHON
1283 if (i == TCL_ERROR) {
1284 *(e->res) = NULL;
1285 *(e->exc_type) = NULL;
1286 *(e->exc_tb) = NULL;
1287 *(e->exc_value) = PyObject_CallFunction(
1288 Tkinter_TclError, "s",
1289 Tcl_GetStringResult(e->self->interp));
1290 }
1291 else {
1292 *(e->res) = Tkapp_CallResult(e->self);
1293 }
1294 LEAVE_PYTHON
Guilherme Polo14ff18d2009-02-06 22:26:22 +00001295
1296 Tkapp_CallDeallocArgs(objv, objStore, objc);
1297done:
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001298 /* Wake up calling thread. */
1299 Tcl_MutexLock(&call_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00001300 Tcl_ConditionNotify(e->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001301 Tcl_MutexUnlock(&call_mutex);
1302 return 1;
1303}
1304
1305/* This is the main entry point for calling a Tcl command.
1306 It supports three cases, with regard to threading:
1307 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1308 the context of the calling thread.
1309 2. Tcl is threaded, caller of the command is in the interpreter thread:
1310 Execute the command in the calling thread. Since the Tcl lock will
1311 not be used, we can merge that with case 1.
1312 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1313 the interpreter thread. Allocation of Tcl objects needs to occur in the
1314 interpreter thread, so we ship the PyObject* args to the target thread,
1315 and perform processing there. */
1316
1317static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001318Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001319{
1320 Tcl_Obj *objStore[ARGSZ];
1321 Tcl_Obj **objv = NULL;
1322 int objc, i;
1323 PyObject *res = NULL;
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001324 TkappObject *self = (TkappObject*)selfptr;
Guilherme Polo23fe2a82009-02-02 21:08:32 +00001325 int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001326
Kurt B. Kaiserd67a3b92007-07-05 22:03:39 +00001327 /* If args is a single tuple, replace with contents of tuple */
1328 if (1 == PyTuple_Size(args)){
1329 PyObject* item = PyTuple_GetItem(args, 0);
1330 if (PyTuple_Check(item))
1331 args = item;
1332 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001333#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001334 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1335 /* We cannot call the command directly. Instead, we must
1336 marshal the parameters to the interpreter thread. */
1337 Tkapp_CallEvent *ev;
Guilherme Polo363161a2009-02-06 22:48:07 +00001338 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001339 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001340 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001341 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001342 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1343 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1344 ev->self = self;
1345 ev->args = args;
1346 ev->res = &res;
1347 ev->exc_type = &exc_type;
1348 ev->exc_value = &exc_value;
1349 ev->exc_tb = &exc_tb;
Guilherme Polo363161a2009-02-06 22:48:07 +00001350 ev->done = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001351
Guilherme Polo363161a2009-02-06 22:48:07 +00001352 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001353
1354 if (res == NULL) {
1355 if (exc_type)
1356 PyErr_Restore(exc_type, exc_value, exc_tb);
1357 else
1358 PyErr_SetObject(Tkinter_TclError, exc_value);
1359 }
Guilherme Polo363161a2009-02-06 22:48:07 +00001360 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001361 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001362 else
1363#endif
1364 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001365
1366 objv = Tkapp_CallArgs(args, objStore, &objc);
1367 if (!objv)
1368 return NULL;
1369
1370 ENTER_TCL
1371
1372 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1373
1374 ENTER_OVERLAP
1375
1376 if (i == TCL_ERROR)
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001377 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001378 else
1379 res = Tkapp_CallResult(self);
1380
1381 LEAVE_OVERLAP_TCL
1382
1383 Tkapp_CallDeallocArgs(objv, objStore, objc);
1384 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001385 return res;
1386}
1387
1388
1389static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001390Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001391{
Guido van Rossum212643f1998-04-29 16:22:14 +00001392 /* Could do the same here as for Tkapp_Call(), but this is not used
1393 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1394 way for the user to do what all its Global* variants do (save and
1395 reset the scope pointer, call the local version, restore the saved
1396 scope pointer). */
1397
Guido van Rossum62320c91998-06-15 04:36:09 +00001398 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001399 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001400
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001401 CHECK_TCL_APPARTMENT;
1402
Guido van Rossum62320c91998-06-15 04:36:09 +00001403 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001404 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001405 int err;
1406 ENTER_TCL
1407 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001408 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001409 if (err == TCL_ERROR)
1410 res = Tkinter_Error(self);
1411 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001412 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001413 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001414 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001415 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001416
1417 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001418}
1419
1420static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001421Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001422{
Barry Warsawfa701a81997-01-16 00:15:11 +00001423 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001424 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001425 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001426
Guido van Rossum43713e52000-02-29 13:59:29 +00001427 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001428 return NULL;
1429
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001430 CHECK_TCL_APPARTMENT;
1431
Guido van Rossum00d93061998-05-28 23:06:38 +00001432 ENTER_TCL
1433 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001434 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001435 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001436 res = Tkinter_Error(self);
1437 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001438 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001439 LEAVE_OVERLAP_TCL
1440 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001441}
1442
1443static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001444Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001445{
Barry Warsawfa701a81997-01-16 00:15:11 +00001446 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001447 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001448 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001449
Guido van Rossum43713e52000-02-29 13:59:29 +00001450 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001451 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001452
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001453 CHECK_TCL_APPARTMENT;
1454
Guido van Rossum00d93061998-05-28 23:06:38 +00001455 ENTER_TCL
1456 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001457 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001458 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001459 res = Tkinter_Error(self);
1460 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001461 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001462 LEAVE_OVERLAP_TCL
1463 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001464}
1465
1466static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001467Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001468{
Barry Warsawfa701a81997-01-16 00:15:11 +00001469 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001470 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001471 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001472
Guido van Rossum43713e52000-02-29 13:59:29 +00001473 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001474 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001475
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001476 CHECK_TCL_APPARTMENT;
1477
Guido van Rossum00d93061998-05-28 23:06:38 +00001478 ENTER_TCL
1479 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001480 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001481 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001482 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001483
Guido van Rossum62320c91998-06-15 04:36:09 +00001484 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001485 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001486 LEAVE_OVERLAP_TCL
1487 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001488}
1489
1490static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001491Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001492{
Barry Warsawfa701a81997-01-16 00:15:11 +00001493 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001494 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001495 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001496
Guido van Rossum35d43371997-08-02 00:09:09 +00001497 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001498 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001499
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001500 CHECK_TCL_APPARTMENT;
1501
Guido van Rossum00d93061998-05-28 23:06:38 +00001502 ENTER_TCL
1503 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001504 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001505 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001506 res = Tkinter_Error(self);
1507 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001508 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001509 LEAVE_OVERLAP_TCL
1510 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001511}
1512
1513static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001514Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001515{
Barry Warsawfa701a81997-01-16 00:15:11 +00001516 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001517
Guido van Rossum43713e52000-02-29 13:59:29 +00001518 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001519 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001520 CHECK_TCL_APPARTMENT;
1521
Guido van Rossum00d93061998-05-28 23:06:38 +00001522 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001523 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001524 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001525
Barry Warsawfa701a81997-01-16 00:15:11 +00001526 Py_INCREF(Py_None);
1527 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001528}
1529
Barry Warsawfa701a81997-01-16 00:15:11 +00001530
1531
Guido van Rossum18468821994-06-20 07:49:28 +00001532/** Tcl Variable **/
1533
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001534TCL_DECLARE_MUTEX(var_mutex)
1535
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001536typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001537typedef struct VarEvent {
1538 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001539 PyObject *self;
1540 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001541 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001542 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001543 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001544 PyObject **exc_type;
1545 PyObject **exc_val;
Guilherme Polo363161a2009-02-06 22:48:07 +00001546 Tcl_Condition *cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001547} VarEvent;
1548
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001549static int
1550varname_converter(PyObject *in, void *_out)
1551{
1552 char **out = (char**)_out;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001553 if (PyString_Check(in)) {
1554 *out = PyString_AsString(in);
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001555 return 1;
1556 }
1557 if (PyTclObject_Check(in)) {
1558 *out = PyTclObject_TclString(in);
1559 return 1;
1560 }
1561 /* XXX: Should give diagnostics. */
1562 return 0;
1563}
1564
Martin v. Löwis111c1802008-06-13 07:47:47 +00001565static void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001566var_perform(VarEvent *ev)
1567{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001568 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1569 if (!*(ev->res)) {
1570 PyObject *exc, *val, *tb;
1571 PyErr_Fetch(&exc, &val, &tb);
1572 PyErr_NormalizeException(&exc, &val, &tb);
1573 *(ev->exc_type) = exc;
1574 *(ev->exc_val) = val;
1575 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001576 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001577
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001578}
1579
1580static int
1581var_proc(VarEvent* ev, int flags)
1582{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001583 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001584 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001585 Tcl_MutexLock(&var_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00001586 Tcl_ConditionNotify(ev->cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001587 Tcl_MutexUnlock(&var_mutex);
1588 LEAVE_PYTHON
1589 return 1;
1590}
1591
1592static PyObject*
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001593var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001594{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001595 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisa9656492003-03-30 08:44:58 +00001596#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001597 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001598 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001599 VarEvent *ev;
1600 PyObject *res, *exc_type, *exc_val;
Guilherme Polo363161a2009-02-06 22:48:07 +00001601 Tcl_Condition cond = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001602
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001603 /* The current thread is not the interpreter thread. Marshal
1604 the call to the interpreter thread, then wait for
1605 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001606 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001607 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001608
1609 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1610
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001611 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001612 ev->args = args;
1613 ev->flags = flags;
1614 ev->func = func;
1615 ev->res = &res;
1616 ev->exc_type = &exc_type;
1617 ev->exc_val = &exc_val;
Guilherme Polo363161a2009-02-06 22:48:07 +00001618 ev->cond = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001619 ev->ev.proc = (Tcl_EventProc*)var_proc;
Guilherme Polo363161a2009-02-06 22:48:07 +00001620 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
1621 Tcl_ConditionFinalize(&cond);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001622 if (!res) {
1623 PyErr_SetObject(exc_type, exc_val);
1624 Py_DECREF(exc_type);
1625 Py_DECREF(exc_val);
1626 return NULL;
1627 }
1628 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001629 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001630#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001631 /* Tcl is not threaded, or this is the interpreter thread. */
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00001632 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001633}
1634
Guido van Rossum18468821994-06-20 07:49:28 +00001635static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001636SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001637{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001638 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001639 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001640 PyObject *res = NULL;
1641 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001642
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001643 if (PyArg_ParseTuple(args, "O&O:setvar",
1644 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001645 /* XXX Acquire tcl lock??? */
1646 newval = AsObj(newValue);
1647 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001648 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001649 ENTER_TCL
1650 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1651 newval, flags);
1652 ENTER_OVERLAP
1653 if (!ok)
1654 Tkinter_Error(self);
1655 else {
1656 res = Py_None;
1657 Py_INCREF(res);
1658 }
1659 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001660 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001661 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001662 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001663 if (PyArg_ParseTuple(args, "ssO:setvar",
1664 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001665 /* XXX must hold tcl lock already??? */
1666 newval = AsObj(newValue);
1667 ENTER_TCL
1668 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1669 ENTER_OVERLAP
1670 if (!ok)
1671 Tkinter_Error(self);
1672 else {
1673 res = Py_None;
1674 Py_INCREF(res);
1675 }
1676 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001677 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001678 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001679 return NULL;
1680 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001681 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001682 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001683}
1684
1685static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001686Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001687{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001688 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001689}
1690
1691static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001692Tkapp_GlobalSetVar(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(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001695}
1696
Barry Warsawfa701a81997-01-16 00:15:11 +00001697
1698
Guido van Rossum18468821994-06-20 07:49:28 +00001699static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001700GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001701{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001702 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001703 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001704 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001705
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001706 if (!PyArg_ParseTuple(args, "O&|s:getvar",
1707 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001708 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001709
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001710 ENTER_TCL
1711 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1712 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001713 if (tres == NULL) {
1714 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1715 } else {
1716 if (((TkappObject*)self)->wantobjects) {
1717 res = FromObj(self, tres);
1718 }
1719 else {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001720 res = PyString_FromString(Tcl_GetString(tres));
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001721 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001722 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001723 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001724 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001725}
1726
1727static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001728Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001729{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001730 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001731}
1732
1733static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001734Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001735{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001736 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001737}
1738
Barry Warsawfa701a81997-01-16 00:15:11 +00001739
1740
Guido van Rossum18468821994-06-20 07:49:28 +00001741static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001742UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001743{
Guido van Rossum35d43371997-08-02 00:09:09 +00001744 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001745 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001746 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001747
Guido van Rossum43713e52000-02-29 13:59:29 +00001748 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001749 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001750
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001751 ENTER_TCL
1752 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1753 ENTER_OVERLAP
1754 if (code == TCL_ERROR)
1755 res = Tkinter_Error(self);
1756 else {
1757 Py_INCREF(Py_None);
1758 res = Py_None;
1759 }
1760 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001761 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001762}
1763
1764static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001765Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001766{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001767 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001768}
1769
1770static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001771Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001772{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001773 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001774}
1775
Barry Warsawfa701a81997-01-16 00:15:11 +00001776
1777
Guido van Rossum18468821994-06-20 07:49:28 +00001778/** Tcl to Python **/
1779
1780static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001781Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001782{
Barry Warsawfa701a81997-01-16 00:15:11 +00001783 char *s;
1784 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001785
Martin v. Löwisffad6332002-11-26 09:28:05 +00001786 if (PyTuple_Size(args) == 1) {
1787 PyObject* o = PyTuple_GetItem(args, 0);
1788 if (PyInt_Check(o)) {
1789 Py_INCREF(o);
1790 return o;
1791 }
1792 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001793 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001794 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001795 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001796 return Tkinter_Error(self);
1797 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001798}
1799
1800static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001801Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001802{
Barry Warsawfa701a81997-01-16 00:15:11 +00001803 char *s;
1804 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001805
Martin v. Löwisffad6332002-11-26 09:28:05 +00001806 if (PyTuple_Size(args) == 1) {
1807 PyObject *o = PyTuple_GetItem(args, 0);
1808 if (PyFloat_Check(o)) {
1809 Py_INCREF(o);
1810 return o;
1811 }
1812 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001813 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001814 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001815 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001816 return Tkinter_Error(self);
1817 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001818}
1819
1820static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001821Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001822{
Barry Warsawfa701a81997-01-16 00:15:11 +00001823 char *s;
1824 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001825
Martin v. Löwisffad6332002-11-26 09:28:05 +00001826 if (PyTuple_Size(args) == 1) {
1827 PyObject *o = PyTuple_GetItem(args, 0);
1828 if (PyInt_Check(o)) {
1829 Py_INCREF(o);
1830 return o;
1831 }
1832 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001833 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001834 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001835 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1836 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001837 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001838}
1839
1840static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001841Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001842{
Barry Warsawfa701a81997-01-16 00:15:11 +00001843 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001844 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001845 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001846
Guido van Rossum43713e52000-02-29 13:59:29 +00001847 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001848 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001849
1850 CHECK_TCL_APPARTMENT;
1851
Guido van Rossum00d93061998-05-28 23:06:38 +00001852 ENTER_TCL
1853 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001854 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001855 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001856 res = Tkinter_Error(self);
1857 else
1858 res = Py_BuildValue("s", Tkapp_Result(self));
1859 LEAVE_OVERLAP_TCL
1860 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001861}
1862
1863static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001864Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001865{
Barry Warsawfa701a81997-01-16 00:15:11 +00001866 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001867 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001868 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001869 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001870
Guido van Rossum43713e52000-02-29 13:59:29 +00001871 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001872 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001873
1874 CHECK_TCL_APPARTMENT;
1875
Guido van Rossum00d93061998-05-28 23:06:38 +00001876 ENTER_TCL
1877 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001878 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001879 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001880 res = Tkinter_Error(self);
1881 else
1882 res = Py_BuildValue("l", v);
1883 LEAVE_OVERLAP_TCL
1884 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001885}
1886
1887static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001888Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001889{
Barry Warsawfa701a81997-01-16 00:15:11 +00001890 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001891 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001892 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001893 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001894
Guido van Rossum43713e52000-02-29 13:59:29 +00001895 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001896 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001897 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001898 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001899 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001900 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001901 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001902 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001903 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001904 res = Tkinter_Error(self);
1905 else
1906 res = Py_BuildValue("d", v);
1907 LEAVE_OVERLAP_TCL
1908 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001909}
1910
1911static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001912Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001913{
Barry Warsawfa701a81997-01-16 00:15:11 +00001914 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001915 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001916 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001917 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001918
Guido van Rossum43713e52000-02-29 13:59:29 +00001919 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001920 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001921 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001922 ENTER_TCL
1923 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001924 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001925 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001926 res = Tkinter_Error(self);
1927 else
1928 res = Py_BuildValue("i", v);
1929 LEAVE_OVERLAP_TCL
1930 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001931}
1932
Barry Warsawfa701a81997-01-16 00:15:11 +00001933
1934
Guido van Rossum18468821994-06-20 07:49:28 +00001935static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001936Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001937{
Barry Warsawfa701a81997-01-16 00:15:11 +00001938 char *list;
1939 int argc;
1940 char **argv;
1941 PyObject *v;
1942 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001943
Martin v. Löwisffad6332002-11-26 09:28:05 +00001944 if (PyTuple_Size(args) == 1) {
1945 v = PyTuple_GetItem(args, 0);
1946 if (PyTuple_Check(v)) {
1947 Py_INCREF(v);
1948 return v;
1949 }
1950 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001951 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001952 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001953
Neal Norwitzd1c55102003-05-29 00:17:03 +00001954 if (Tcl_SplitList(Tkapp_Interp(self), list,
1955 &argc, &argv) == TCL_ERROR) {
1956 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001957 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001958 }
Guido van Rossum18468821994-06-20 07:49:28 +00001959
Barry Warsawfa701a81997-01-16 00:15:11 +00001960 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001961 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001962
Barry Warsawfa701a81997-01-16 00:15:11 +00001963 for (i = 0; i < argc; i++) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001964 PyObject *s = PyString_FromString(argv[i]);
Barry Warsawfa701a81997-01-16 00:15:11 +00001965 if (!s || PyTuple_SetItem(v, i, s)) {
1966 Py_DECREF(v);
1967 v = NULL;
1968 goto finally;
1969 }
1970 }
Guido van Rossum18468821994-06-20 07:49:28 +00001971
Barry Warsawfa701a81997-01-16 00:15:11 +00001972 finally:
1973 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001974 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001975 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001976}
1977
1978static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001979Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001980{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001981 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001982 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001983
Martin v. Löwisffad6332002-11-26 09:28:05 +00001984 if (PyTuple_Size(args) == 1) {
1985 PyObject* o = PyTuple_GetItem(args, 0);
1986 if (PyTuple_Check(o)) {
1987 o = SplitObj(o);
1988 return o;
1989 }
1990 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001991 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001992 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00001993 v = Split(list);
1994 PyMem_Free(list);
1995 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001996}
1997
1998static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001999Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002000{
Barry Warsawfa701a81997-01-16 00:15:11 +00002001 char *s = Merge(args);
2002 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002003
Barry Warsawfa701a81997-01-16 00:15:11 +00002004 if (s) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002005 res = PyString_FromString(s);
Barry Warsawfa701a81997-01-16 00:15:11 +00002006 ckfree(s);
2007 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002008
2009 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00002010}
2011
Barry Warsawfa701a81997-01-16 00:15:11 +00002012
2013
Guido van Rossum18468821994-06-20 07:49:28 +00002014/** Tcl Command **/
2015
Guido van Rossum00d93061998-05-28 23:06:38 +00002016/* Client data struct */
2017typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00002018 PyObject *self;
2019 PyObject *func;
2020} PythonCmd_ClientData;
2021
2022static int
Fred Drake509d79a2000-07-08 04:04:38 +00002023PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00002024{
2025 errorInCmd = 1;
2026 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2027 LEAVE_PYTHON
2028 return TCL_ERROR;
2029}
2030
Guido van Rossum18468821994-06-20 07:49:28 +00002031/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00002032 * function or method.
2033 */
Guido van Rossum18468821994-06-20 07:49:28 +00002034static int
Fred Drake509d79a2000-07-08 04:04:38 +00002035PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00002036{
Guido van Rossum00d93061998-05-28 23:06:38 +00002037 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002038 PyObject *self, *func, *arg, *res;
Guido van Rossum2834b972000-10-06 16:58:26 +00002039 int i, rv;
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002040 Tcl_Obj *obj_res;
Guido van Rossum18468821994-06-20 07:49:28 +00002041
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002042 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002043
Barry Warsawfa701a81997-01-16 00:15:11 +00002044 /* TBD: no error checking here since we know, via the
2045 * Tkapp_CreateCommand() that the client data is a two-tuple
2046 */
Guido van Rossum00d93061998-05-28 23:06:38 +00002047 self = data->self;
2048 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00002049
Barry Warsawfa701a81997-01-16 00:15:11 +00002050 /* Create argument list (argv1, ..., argvN) */
2051 if (!(arg = PyTuple_New(argc - 1)))
2052 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00002053
Barry Warsawfa701a81997-01-16 00:15:11 +00002054 for (i = 0; i < (argc - 1); i++) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002055 PyObject *s = PyString_FromString(argv[i + 1]);
Barry Warsawfa701a81997-01-16 00:15:11 +00002056 if (!s || PyTuple_SetItem(arg, i, s)) {
2057 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00002058 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00002059 }
2060 }
2061 res = PyEval_CallObject(func, arg);
2062 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00002063
Barry Warsawfa701a81997-01-16 00:15:11 +00002064 if (res == NULL)
2065 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00002066
Martin v. Löwis17cb5cf2008-01-01 21:05:17 +00002067 obj_res = AsObj(res);
2068 if (obj_res == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002069 Py_DECREF(res);
2070 return PythonCmd_Error(interp);
2071 }
Guido van Rossum2834b972000-10-06 16:58:26 +00002072 else {
Guilherme Polo3768b2f2009-03-07 01:47:49 +00002073 Tcl_SetObjResult(interp, obj_res);
Guido van Rossum2834b972000-10-06 16:58:26 +00002074 rv = TCL_OK;
2075 }
2076
Barry Warsawfa701a81997-01-16 00:15:11 +00002077 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00002078
Guido van Rossum00d93061998-05-28 23:06:38 +00002079 LEAVE_PYTHON
2080
Guido van Rossum2834b972000-10-06 16:58:26 +00002081 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002082}
2083
2084static void
Fred Drake509d79a2000-07-08 04:04:38 +00002085PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002086{
Guido van Rossum00d93061998-05-28 23:06:38 +00002087 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2088
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002089 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002090 Py_XDECREF(data->self);
2091 Py_XDECREF(data->func);
2092 PyMem_DEL(data);
2093 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002094}
2095
Barry Warsawfa701a81997-01-16 00:15:11 +00002096
2097
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002098
2099TCL_DECLARE_MUTEX(command_mutex)
2100
2101typedef struct CommandEvent{
2102 Tcl_Event ev;
2103 Tcl_Interp* interp;
2104 char *name;
2105 int create;
2106 int *status;
2107 ClientData *data;
Guilherme Polo363161a2009-02-06 22:48:07 +00002108 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002109} CommandEvent;
2110
2111static int
2112Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002113{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002114 if (ev->create)
2115 *ev->status = Tcl_CreateCommand(
2116 ev->interp, ev->name, PythonCmd,
2117 ev->data, PythonCmdDelete) == NULL;
2118 else
2119 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2120 Tcl_MutexLock(&command_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00002121 Tcl_ConditionNotify(ev->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002122 Tcl_MutexUnlock(&command_mutex);
2123 return 1;
2124}
2125
2126static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002127Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002128{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002129 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002130 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002131 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002132 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002133 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002134
Guido van Rossum43713e52000-02-29 13:59:29 +00002135 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002136 return NULL;
2137 if (!PyCallable_Check(func)) {
2138 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002139 return NULL;
2140 }
Guido van Rossum18468821994-06-20 07:49:28 +00002141
Martin v. Löwisa9656492003-03-30 08:44:58 +00002142#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002143 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002144 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002145 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002146#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002147
Guido van Rossum00d93061998-05-28 23:06:38 +00002148 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002149 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002150 return PyErr_NoMemory();
Neal Norwitzce5b3c32006-07-16 02:02:57 +00002151 Py_INCREF(self);
2152 Py_INCREF(func);
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002153 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002154 data->func = func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002155
2156 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo363161a2009-02-06 22:48:07 +00002157 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002158 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2159 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2160 ev->interp = self->interp;
2161 ev->create = 1;
2162 ev->name = cmdName;
2163 ev->data = (ClientData)data;
2164 ev->status = &err;
Guilherme Polo363161a2009-02-06 22:48:07 +00002165 ev->done = &cond;
2166 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
2167 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002168 }
2169 else {
2170 ENTER_TCL
2171 err = Tcl_CreateCommand(
2172 Tkapp_Interp(self), cmdName, PythonCmd,
2173 (ClientData)data, PythonCmdDelete) == NULL;
2174 LEAVE_TCL
2175 }
2176 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002177 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002178 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002179 return NULL;
2180 }
Guido van Rossum18468821994-06-20 07:49:28 +00002181
Barry Warsawfa701a81997-01-16 00:15:11 +00002182 Py_INCREF(Py_None);
2183 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002184}
2185
Barry Warsawfa701a81997-01-16 00:15:11 +00002186
2187
Guido van Rossum18468821994-06-20 07:49:28 +00002188static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002189Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002190{
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002191 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002192 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002193 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002194
Guido van Rossum43713e52000-02-29 13:59:29 +00002195 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002196 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002197 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo363161a2009-02-06 22:48:07 +00002198 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002199 CommandEvent *ev;
2200 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2201 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2202 ev->interp = self->interp;
2203 ev->create = 0;
2204 ev->name = cmdName;
2205 ev->status = &err;
Guilherme Polo363161a2009-02-06 22:48:07 +00002206 ev->done = &cond;
2207 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002208 &command_mutex);
Guilherme Polo363161a2009-02-06 22:48:07 +00002209 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002210 }
2211 else {
2212 ENTER_TCL
2213 err = Tcl_DeleteCommand(self->interp, cmdName);
2214 LEAVE_TCL
2215 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002216 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002217 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2218 return NULL;
2219 }
2220 Py_INCREF(Py_None);
2221 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002222}
2223
Barry Warsawfa701a81997-01-16 00:15:11 +00002224
2225
Guido van Rossum00d93061998-05-28 23:06:38 +00002226#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002227/** File Handler **/
2228
Guido van Rossum00d93061998-05-28 23:06:38 +00002229typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002230 PyObject *func;
2231 PyObject *file;
2232 int id;
2233 struct _fhcdata *next;
2234} FileHandler_ClientData;
2235
2236static FileHandler_ClientData *HeadFHCD;
2237
2238static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002239NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002240{
2241 FileHandler_ClientData *p;
2242 p = PyMem_NEW(FileHandler_ClientData, 1);
2243 if (p != NULL) {
2244 Py_XINCREF(func);
2245 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002246 p->func = func;
2247 p->file = file;
2248 p->id = id;
2249 p->next = HeadFHCD;
2250 HeadFHCD = p;
2251 }
2252 return p;
2253}
2254
2255static void
Fred Drake509d79a2000-07-08 04:04:38 +00002256DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002257{
2258 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002259
2260 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002261 while ((p = *pp) != NULL) {
2262 if (p->id == id) {
2263 *pp = p->next;
2264 Py_XDECREF(p->func);
2265 Py_XDECREF(p->file);
2266 PyMem_DEL(p);
2267 }
2268 else
2269 pp = &p->next;
2270 }
2271}
2272
Guido van Rossuma597dde1995-01-10 20:56:29 +00002273static void
Fred Drake509d79a2000-07-08 04:04:38 +00002274FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002275{
Guido van Rossum00d93061998-05-28 23:06:38 +00002276 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002277 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002278
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002279 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002280 func = data->func;
2281 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002282
Barry Warsawfa701a81997-01-16 00:15:11 +00002283 arg = Py_BuildValue("(Oi)", file, (long) mask);
2284 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002285 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002286
2287 if (res == NULL) {
2288 errorInCmd = 1;
2289 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2290 }
2291 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002292 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002293}
2294
Guido van Rossum18468821994-06-20 07:49:28 +00002295static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002296Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2297 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002298{
Guido van Rossum00d93061998-05-28 23:06:38 +00002299 FileHandler_ClientData *data;
2300 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002301 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002302
Guilherme Poloe7f14032009-01-03 21:51:09 +00002303 if (!self && Py_Py3kWarningFlag) {
2304 if (PyErr_Warn(PyExc_DeprecationWarning,
2305 "_tkinter.createfilehandler is gone in 3.x") < 0)
2306 return NULL;
2307 }
2308
Guido van Rossum2834b972000-10-06 16:58:26 +00002309 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2310 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002311 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002312
Martin v. Löwisa9656492003-03-30 08:44:58 +00002313#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002314 if (!self && !tcl_lock) {
2315 /* We don't have the Tcl lock since Tcl is threaded. */
2316 PyErr_SetString(PyExc_RuntimeError,
2317 "_tkinter.createfilehandler not supported "
2318 "for threaded Tcl");
2319 return NULL;
2320 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002321#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002322
2323 if (self) {
2324 CHECK_TCL_APPARTMENT;
2325 }
2326
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002327 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002328 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002329 return NULL;
2330 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002331 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002332 return NULL;
2333 }
2334
Guido van Rossuma80649b2000-03-28 20:07:05 +00002335 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002336 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002337 return NULL;
2338
Barry Warsawfa701a81997-01-16 00:15:11 +00002339 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002340 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002341 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002342 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002343 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002344 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002345}
2346
2347static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002348Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002349{
Barry Warsawfa701a81997-01-16 00:15:11 +00002350 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002351 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002352
Guilherme Poloe7f14032009-01-03 21:51:09 +00002353 if (!self && Py_Py3kWarningFlag) {
2354 if (PyErr_Warn(PyExc_DeprecationWarning,
2355 "_tkinter.deletefilehandler is gone in 3.x") < 0)
2356 return NULL;
2357 }
2358
Guido van Rossum43713e52000-02-29 13:59:29 +00002359 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002360 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002361
Martin v. Löwisa9656492003-03-30 08:44:58 +00002362#ifdef WITH_THREAD
Neal Norwitz12e22172003-03-03 21:16:39 +00002363 if (!self && !tcl_lock) {
2364 /* We don't have the Tcl lock since Tcl is threaded. */
2365 PyErr_SetString(PyExc_RuntimeError,
2366 "_tkinter.deletefilehandler not supported "
2367 "for threaded Tcl");
2368 return NULL;
2369 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002370#endif
Neal Norwitz12e22172003-03-03 21:16:39 +00002371
2372 if (self) {
2373 CHECK_TCL_APPARTMENT;
2374 }
2375
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002376 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002377 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002378 return NULL;
2379
Guido van Rossuma80649b2000-03-28 20:07:05 +00002380 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002381
Barry Warsawfa701a81997-01-16 00:15:11 +00002382 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002383 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002384 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002385 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002386 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002387 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002388}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002389#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002390
Barry Warsawfa701a81997-01-16 00:15:11 +00002391
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002392/**** Tktt Object (timer token) ****/
2393
Jeremy Hylton938ace62002-07-17 16:30:39 +00002394static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002395
Guido van Rossum00d93061998-05-28 23:06:38 +00002396typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002397 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002398 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002399 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002400} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002401
2402static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002403Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002404{
Barry Warsawfa701a81997-01-16 00:15:11 +00002405 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002406 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002407
Guido van Rossum43713e52000-02-29 13:59:29 +00002408 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002409 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002410 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002411 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002412 v->token = NULL;
2413 }
2414 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002415 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002416 Py_DECREF(func);
2417 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002418 }
2419 Py_INCREF(Py_None);
2420 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002421}
2422
2423static PyMethodDef Tktt_methods[] =
2424{
Neal Norwitzb0493252002-03-31 14:44:22 +00002425 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002426 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002427};
2428
2429static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002430Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002431{
Barry Warsawfa701a81997-01-16 00:15:11 +00002432 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002433
Guido van Rossumb18618d2000-05-03 23:44:39 +00002434 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002435 if (v == NULL)
2436 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002437
Guido van Rossum00d93061998-05-28 23:06:38 +00002438 Py_INCREF(func);
2439 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002440 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002441
2442 /* Extra reference, deleted when called or when handler is deleted */
2443 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002444 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002445}
2446
2447static void
Fred Drake509d79a2000-07-08 04:04:38 +00002448Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002449{
Guido van Rossum00d93061998-05-28 23:06:38 +00002450 TkttObject *v = (TkttObject *)self;
2451 PyObject *func = v->func;
2452
2453 Py_XDECREF(func);
2454
Guido van Rossumb18618d2000-05-03 23:44:39 +00002455 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002456}
2457
Guido van Rossum597ac201998-05-12 14:36:19 +00002458static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002459Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002460{
Barry Warsawfa701a81997-01-16 00:15:11 +00002461 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002462 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002463
Tim Peters885d4572001-11-28 20:27:42 +00002464 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002465 v->func == NULL ? ", handler deleted" : "");
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002466 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002467}
2468
2469static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002470Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002471{
Barry Warsawfa701a81997-01-16 00:15:11 +00002472 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002473}
2474
2475static PyTypeObject Tktt_Type =
2476{
Martin v. Löwis68192102007-07-21 06:55:02 +00002477 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002478 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002479 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002480 0, /*tp_itemsize */
2481 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002482 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00002483 Tktt_GetAttr, /*tp_getattr */
2484 0, /*tp_setattr */
2485 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00002486 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002487 0, /*tp_as_number */
2488 0, /*tp_as_sequence */
2489 0, /*tp_as_mapping */
2490 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002491};
2492
Barry Warsawfa701a81997-01-16 00:15:11 +00002493
2494
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002495/** Timer Handler **/
2496
2497static void
Fred Drake509d79a2000-07-08 04:04:38 +00002498TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002499{
Guido van Rossum00d93061998-05-28 23:06:38 +00002500 TkttObject *v = (TkttObject *)clientData;
2501 PyObject *func = v->func;
2502 PyObject *res;
2503
2504 if (func == NULL)
2505 return;
2506
2507 v->func = NULL;
2508
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002509 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002510
2511 res = PyEval_CallObject(func, NULL);
2512 Py_DECREF(func);
2513 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002514
Barry Warsawfa701a81997-01-16 00:15:11 +00002515 if (res == NULL) {
2516 errorInCmd = 1;
2517 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2518 }
2519 else
2520 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002521
2522 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002523}
2524
2525static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002526Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002527{
Barry Warsawfa701a81997-01-16 00:15:11 +00002528 int milliseconds;
2529 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002530 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002531
Guilherme Poloe7f14032009-01-03 21:51:09 +00002532 if (!self && Py_Py3kWarningFlag) {
2533 if (PyErr_Warn(PyExc_DeprecationWarning,
2534 "_tkinter.createtimerhandler is gone in 3.x") < 0)
2535 return NULL;
2536 }
2537
Guido van Rossum2834b972000-10-06 16:58:26 +00002538 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2539 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002540 return NULL;
2541 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002542 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002543 return NULL;
2544 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002545
Martin v. Löwisa9656492003-03-30 08:44:58 +00002546#ifdef WITH_THREAD
Martin v. Löwis7f134892003-03-03 10:40:01 +00002547 if (!self && !tcl_lock) {
2548 /* We don't have the Tcl lock since Tcl is threaded. */
2549 PyErr_SetString(PyExc_RuntimeError,
2550 "_tkinter.createtimerhandler not supported "
2551 "for threaded Tcl");
2552 return NULL;
2553 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002554#endif
Martin v. Löwis7f134892003-03-03 10:40:01 +00002555
2556 if (self) {
2557 CHECK_TCL_APPARTMENT;
2558 }
2559
Guido van Rossum00d93061998-05-28 23:06:38 +00002560 v = Tktt_New(func);
Neal Norwitz5f17d9a2006-08-12 02:33:36 +00002561 if (v) {
2562 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2563 (ClientData)v);
2564 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002565
Guido van Rossum00d93061998-05-28 23:06:38 +00002566 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002567}
2568
Barry Warsawfa701a81997-01-16 00:15:11 +00002569
Guido van Rossum18468821994-06-20 07:49:28 +00002570/** Event Loop **/
2571
Guido van Rossum18468821994-06-20 07:49:28 +00002572static PyObject *
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002573Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002574{
Barry Warsawfa701a81997-01-16 00:15:11 +00002575 int threshold = 0;
Andrew M. Kuchling36f6d772006-06-03 19:02:35 +00002576 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002577#ifdef WITH_THREAD
2578 PyThreadState *tstate = PyThreadState_Get();
2579#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002580
Guilherme Poloe7f14032009-01-03 21:51:09 +00002581 if (!self && Py_Py3kWarningFlag) {
2582 if (PyErr_Warn(PyExc_DeprecationWarning,
2583 "_tkinter.mainloop is gone in 3.x") < 0)
2584 return NULL;
2585 }
2586
Guido van Rossum43713e52000-02-29 13:59:29 +00002587 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002588 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002589
Martin v. Löwisa9656492003-03-30 08:44:58 +00002590#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002591 if (!self && !tcl_lock) {
2592 /* We don't have the Tcl lock since Tcl is threaded. */
2593 PyErr_SetString(PyExc_RuntimeError,
2594 "_tkinter.mainloop not supported "
2595 "for threaded Tcl");
2596 return NULL;
2597 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00002598#endif
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002599
2600 if (self) {
2601 CHECK_TCL_APPARTMENT;
2602 self->dispatching = 1;
2603 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002604
Barry Warsawfa701a81997-01-16 00:15:11 +00002605 quitMainLoop = 0;
2606 while (Tk_GetNumMainWindows() > threshold &&
2607 !quitMainLoop &&
2608 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002609 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002610 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002611
2612#ifdef WITH_THREAD
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002613 if (self && self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002614 /* Allow other Python threads to run. */
2615 ENTER_TCL
2616 result = Tcl_DoOneEvent(0);
2617 LEAVE_TCL
2618 }
2619 else {
2620 Py_BEGIN_ALLOW_THREADS
2621 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2622 tcl_tstate = tstate;
2623 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2624 tcl_tstate = NULL;
2625 if(tcl_lock)PyThread_release_lock(tcl_lock);
2626 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002627 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002628 Py_END_ALLOW_THREADS
2629 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002630#else
2631 result = Tcl_DoOneEvent(0);
2632#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002633
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002634 if (PyErr_CheckSignals() != 0) {
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002635 if (self)
2636 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002637 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002638 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002639 if (result < 0)
2640 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002641 }
Martin v. Löwis6a759d92003-01-04 08:36:57 +00002642 if (self)
2643 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002644 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002645
Barry Warsawfa701a81997-01-16 00:15:11 +00002646 if (errorInCmd) {
2647 errorInCmd = 0;
2648 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2649 excInCmd = valInCmd = trbInCmd = NULL;
2650 return NULL;
2651 }
2652 Py_INCREF(Py_None);
2653 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002654}
2655
2656static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002657Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002658{
Guido van Rossum35d43371997-08-02 00:09:09 +00002659 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002660 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002661
Guilherme Poloe7f14032009-01-03 21:51:09 +00002662 if (!self && Py_Py3kWarningFlag) {
2663 if (PyErr_Warn(PyExc_DeprecationWarning,
2664 "_tkinter.dooneevent is gone in 3.x") < 0)
2665 return NULL;
2666 }
2667
Guido van Rossum43713e52000-02-29 13:59:29 +00002668 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002669 return NULL;
2670
Guido van Rossum00d93061998-05-28 23:06:38 +00002671 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002672 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002673 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002674 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002675}
2676
2677static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002678Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002679{
2680
Guilherme Poloe7f14032009-01-03 21:51:09 +00002681 if (!self && Py_Py3kWarningFlag) {
2682 if (PyErr_Warn(PyExc_DeprecationWarning,
2683 "_tkinter.createfilehandler is gone in 3.x") < 0)
2684 return NULL;
2685 }
2686
Guido van Rossum43713e52000-02-29 13:59:29 +00002687 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002688 return NULL;
2689
2690 quitMainLoop = 1;
2691 Py_INCREF(Py_None);
2692 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002693}
2694
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002695static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002696Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002697{
2698
Guido van Rossum43713e52000-02-29 13:59:29 +00002699 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002700 return NULL;
2701
2702 return PyInt_FromLong((long)Tkapp_Interp(self));
2703}
2704
David Aschere2b4b322004-02-18 05:59:53 +00002705static PyObject *
2706Tkapp_TkInit(PyObject *self, PyObject *args)
2707{
2708 Tcl_Interp *interp = Tkapp_Interp(self);
David Aschere2b4b322004-02-18 05:59:53 +00002709 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002710 int err;
David Aschere2b4b322004-02-18 05:59:53 +00002711
Guilherme Poloa66cf5b2009-02-09 20:50:27 +00002712#ifdef TKINTER_PROTECT_LOADTK
2713 /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the
2714 * first call failed.
2715 * To avoid the deadlock, we just refuse the second call through
2716 * a static variable.
2717 */
2718 if (tk_load_failed) {
2719 PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG);
Martin v. Löwis86725192006-05-01 06:28:01 +00002720 return NULL;
2721 }
Guilherme Poloa66cf5b2009-02-09 20:50:27 +00002722#endif
2723
David Aschere2b4b322004-02-18 05:59:53 +00002724 /* We want to guard against calling Tk_Init() multiple times */
2725 CHECK_TCL_APPARTMENT;
2726 ENTER_TCL
2727 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2728 ENTER_OVERLAP
2729 if (err == TCL_ERROR) {
Martin v. Löwis86725192006-05-01 06:28:01 +00002730 /* This sets an exception, but we cannot return right
2731 away because we need to exit the overlap first. */
2732 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002733 } else {
2734 _tk_exists = Tkapp_Result(self);
2735 }
2736 LEAVE_OVERLAP_TCL
2737 if (err == TCL_ERROR) {
2738 return NULL;
2739 }
2740 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2741 if (Tk_Init(interp) == TCL_ERROR) {
Guilherme Poloa66cf5b2009-02-09 20:50:27 +00002742 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
2743#ifdef TKINTER_PROTECT_LOADTK
2744 tk_load_failed = 1;
2745#endif
David Aschere2b4b322004-02-18 05:59:53 +00002746 return NULL;
2747 }
2748 }
2749 Py_INCREF(Py_None);
2750 return Py_None;
2751}
Barry Warsawfa701a81997-01-16 00:15:11 +00002752
Martin v. Löwisffad6332002-11-26 09:28:05 +00002753static PyObject *
2754Tkapp_WantObjects(PyObject *self, PyObject *args)
2755{
2756
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002757 int wantobjects = -1;
2758 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002759 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002760 if (wantobjects == -1)
2761 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002762 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002763
2764 Py_INCREF(Py_None);
2765 return Py_None;
2766}
2767
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002768static PyObject *
2769Tkapp_WillDispatch(PyObject *self, PyObject *args)
2770{
2771
2772 ((TkappObject*)self)->dispatching = 1;
2773
2774 Py_INCREF(Py_None);
2775 return Py_None;
2776}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002777
Barry Warsawfa701a81997-01-16 00:15:11 +00002778
Guido van Rossum18468821994-06-20 07:49:28 +00002779/**** Tkapp Method List ****/
2780
2781static PyMethodDef Tkapp_methods[] =
2782{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002783 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002784 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Neal Norwitze2e447b2007-05-22 07:16:10 +00002785 {"call", Tkapp_Call, METH_VARARGS},
2786 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002787 {"eval", Tkapp_Eval, METH_VARARGS},
2788 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2789 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2790 {"record", Tkapp_Record, METH_VARARGS},
2791 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2792 {"setvar", Tkapp_SetVar, METH_VARARGS},
2793 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2794 {"getvar", Tkapp_GetVar, METH_VARARGS},
2795 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2796 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2797 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2798 {"getint", Tkapp_GetInt, METH_VARARGS},
2799 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2800 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2801 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2802 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2803 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2804 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2805 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2806 {"split", Tkapp_Split, METH_VARARGS},
Neal Norwitze2e447b2007-05-22 07:16:10 +00002807 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002808 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2809 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002810#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002811 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2812 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002813#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002814 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2815 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2816 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2817 {"quit", Tkapp_Quit, METH_VARARGS},
2818 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002819 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002820 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002821};
2822
Barry Warsawfa701a81997-01-16 00:15:11 +00002823
2824
Guido van Rossum18468821994-06-20 07:49:28 +00002825/**** Tkapp Type Methods ****/
2826
2827static void
Fred Drake509d79a2000-07-08 04:04:38 +00002828Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002829{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002830 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002831 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002832 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002833 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002834 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002835 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002836}
2837
2838static PyObject *
Martin v. Löwis1d519e42006-02-27 23:10:11 +00002839Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002840{
Guido van Rossum35d43371997-08-02 00:09:09 +00002841 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002842}
2843
2844static PyTypeObject Tkapp_Type =
2845{
Martin v. Löwis68192102007-07-21 06:55:02 +00002846 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002847 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002848 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002849 0, /*tp_itemsize */
2850 Tkapp_Dealloc, /*tp_dealloc */
2851 0, /*tp_print */
2852 Tkapp_GetAttr, /*tp_getattr */
2853 0, /*tp_setattr */
2854 0, /*tp_compare */
2855 0, /*tp_repr */
2856 0, /*tp_as_number */
2857 0, /*tp_as_sequence */
2858 0, /*tp_as_mapping */
2859 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002860};
2861
Barry Warsawfa701a81997-01-16 00:15:11 +00002862
2863
Guido van Rossum18468821994-06-20 07:49:28 +00002864/**** Tkinter Module ****/
2865
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002866typedef struct {
2867 PyObject* tuple;
2868 int size; /* current size */
2869 int maxsize; /* allocated size */
2870} FlattenContext;
2871
2872static int
2873_bump(FlattenContext* context, int size)
2874{
Guido van Rossum2834b972000-10-06 16:58:26 +00002875 /* expand tuple to hold (at least) size new items.
2876 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002877
2878 int maxsize = context->maxsize * 2;
2879
2880 if (maxsize < context->size + size)
2881 maxsize = context->size + size;
2882
2883 context->maxsize = maxsize;
2884
Tim Peters4324aa32001-05-28 22:30:08 +00002885 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002886}
2887
2888static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002889_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002890{
2891 /* add tuple or list to argument tuple (recursively) */
2892
2893 int i, size;
2894
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002895 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002896 PyErr_SetString(PyExc_ValueError,
2897 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002898 return 0;
2899 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002900 size = PyList_GET_SIZE(item);
2901 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002902 if (context->size + size > context->maxsize &&
2903 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002904 return 0;
2905 /* copy items to output tuple */
2906 for (i = 0; i < size; i++) {
2907 PyObject *o = PyList_GET_ITEM(item, i);
2908 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002909 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002910 return 0;
2911 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002912 if (context->size + 1 > context->maxsize &&
2913 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002914 return 0;
2915 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002916 PyTuple_SET_ITEM(context->tuple,
2917 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002918 }
2919 }
2920 } else if (PyTuple_Check(item)) {
2921 /* same, for tuples */
2922 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002923 if (context->size + size > context->maxsize &&
2924 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002925 return 0;
2926 for (i = 0; i < size; i++) {
2927 PyObject *o = PyTuple_GET_ITEM(item, i);
2928 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002929 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002930 return 0;
2931 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002932 if (context->size + 1 > context->maxsize &&
2933 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002934 return 0;
2935 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002936 PyTuple_SET_ITEM(context->tuple,
2937 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002938 }
2939 }
2940 } else {
2941 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2942 return 0;
2943 }
2944 return 1;
2945}
2946
2947static PyObject *
2948Tkinter_Flatten(PyObject* self, PyObject* args)
2949{
2950 FlattenContext context;
2951 PyObject* item;
2952
2953 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2954 return NULL;
2955
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002956 context.maxsize = PySequence_Size(item);
Benjamin Petersonb3619be2009-01-30 02:24:39 +00002957 if (context.maxsize < 0)
2958 return NULL;
2959 if (context.maxsize == 0)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002960 return PyTuple_New(0);
2961
2962 context.tuple = PyTuple_New(context.maxsize);
2963 if (!context.tuple)
2964 return NULL;
2965
2966 context.size = 0;
2967
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002968 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002969 return NULL;
2970
Tim Peters4324aa32001-05-28 22:30:08 +00002971 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002972 return NULL;
2973
2974 return context.tuple;
2975}
2976
Guido van Rossum18468821994-06-20 07:49:28 +00002977static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002978Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002979{
Barry Warsawfa701a81997-01-16 00:15:11 +00002980 char *screenName = NULL;
2981 char *baseName = NULL;
2982 char *className = NULL;
2983 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002984 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002985 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002986 int sync = 0; /* pass -sync to wish */
2987 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002988
Guido van Rossum35d43371997-08-02 00:09:09 +00002989 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002990 if (baseName != NULL)
2991 baseName++;
2992 else
2993 baseName = Py_GetProgramName();
2994 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002995
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002996 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002997 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002998 &interactive, &wantobjects, &wantTk,
2999 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00003000 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00003001
Barry Warsawfa701a81997-01-16 00:15:11 +00003002 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00003003 interactive, wantobjects, wantTk,
3004 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00003005}
3006
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003007static PyObject *
3008Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
3009{
3010 int new_val;
3011 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
3012 return NULL;
3013 if (new_val < 0) {
3014 PyErr_SetString(PyExc_ValueError,
3015 "busywaitinterval must be >= 0");
3016 return NULL;
3017 }
3018 Tkinter_busywaitinterval = new_val;
3019 Py_INCREF(Py_None);
3020 return Py_None;
3021}
3022
3023static char setbusywaitinterval_doc[] =
3024"setbusywaitinterval(n) -> None\n\
3025\n\
3026Set the busy-wait interval in milliseconds between successive\n\
3027calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
3028It should be set to a divisor of the maximum time between\n\
3029frames in an animation.";
3030
3031static PyObject *
3032Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
3033{
3034 return PyInt_FromLong(Tkinter_busywaitinterval);
3035}
3036
3037static char getbusywaitinterval_doc[] =
3038"getbusywaitinterval() -> int\n\
3039\n\
3040Return the current busy-wait interval between successive\n\
3041calls to Tcl_DoOneEvent in a threaded Python interpreter.";
3042
Guido van Rossum18468821994-06-20 07:49:28 +00003043static PyMethodDef moduleMethods[] =
3044{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003045 {"_flatten", Tkinter_Flatten, METH_VARARGS},
3046 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00003047#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003048 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
3049 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00003050#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00003051 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
3052 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
3053 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
3054 {"quit", Tkapp_Quit, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003055 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
3056 setbusywaitinterval_doc},
3057 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
3058 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00003059 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00003060};
3061
Guido van Rossum7bf15641998-05-22 18:28:17 +00003062#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003063
3064static int stdin_ready = 0;
3065
Guido van Rossumad4db171998-06-13 13:56:28 +00003066#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00003067static void
Fred Drake509d79a2000-07-08 04:04:38 +00003068MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003069{
3070 stdin_ready = 1;
3071}
Guido van Rossumad4db171998-06-13 13:56:28 +00003072#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003073
Martin v. Löwisa9656492003-03-30 08:44:58 +00003074#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003075static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00003076#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00003077
Guido van Rossum18468821994-06-20 07:49:28 +00003078static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003079EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003080{
Guido van Rossumad4db171998-06-13 13:56:28 +00003081#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00003082 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00003083#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003084#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003085 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003086#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003087 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00003088 errorInCmd = 0;
3089#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00003090 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003091 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00003092#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003093 while (!errorInCmd && !stdin_ready) {
3094 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00003095#ifdef MS_WINDOWS
3096 if (_kbhit()) {
3097 stdin_ready = 1;
3098 break;
3099 }
3100#endif
3101#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00003102 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003103 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00003104 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003105
Guido van Rossum00d93061998-05-28 23:06:38 +00003106 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003107
3108 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003109 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00003110 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003111 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00003112 Py_END_ALLOW_THREADS
3113#else
3114 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003115#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003116
3117 if (result < 0)
3118 break;
3119 }
Guido van Rossumad4db171998-06-13 13:56:28 +00003120#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00003121 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00003122#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003123 if (errorInCmd) {
3124 errorInCmd = 0;
3125 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3126 excInCmd = valInCmd = trbInCmd = NULL;
3127 PyErr_Print();
3128 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003129#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003130 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003131#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003132 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00003133}
Guido van Rossum18468821994-06-20 07:49:28 +00003134
Guido van Rossum00d93061998-05-28 23:06:38 +00003135#endif
3136
Guido van Rossum7bf15641998-05-22 18:28:17 +00003137static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003138EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003139{
Guido van Rossum00d93061998-05-28 23:06:38 +00003140#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003141 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003142#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003143 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003144#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003145 PyOS_InputHook = EventHook;
3146 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003147#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003148}
3149
3150static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003151DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003152{
Guido van Rossum00d93061998-05-28 23:06:38 +00003153#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003154 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3155 PyOS_InputHook = NULL;
3156 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003157#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003158}
3159
Barry Warsawfa701a81997-01-16 00:15:11 +00003160
3161/* all errors will be checked in one fell swoop in init_tkinter() */
3162static void
Fred Drake509d79a2000-07-08 04:04:38 +00003163ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003164{
3165 PyObject *v = PyInt_FromLong(val);
3166 if (v) {
3167 PyDict_SetItemString(d, name, v);
3168 Py_DECREF(v);
3169 }
3170}
3171static void
Fred Drake509d79a2000-07-08 04:04:38 +00003172ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003173{
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003174 PyObject *v = PyString_FromString(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003175 if (v) {
3176 PyDict_SetItemString(d, name, v);
3177 Py_DECREF(v);
3178 }
3179}
3180
3181
Mark Hammond62b1ab12002-07-23 06:31:15 +00003182PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003183init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003184{
Barry Warsawfa701a81997-01-16 00:15:11 +00003185 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00003186
Christian Heimese93237d2007-12-19 02:37:44 +00003187 Py_TYPE(&Tkapp_Type) = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00003188
3189#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003190 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003191#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003192
Barry Warsawfa701a81997-01-16 00:15:11 +00003193 m = Py_InitModule("_tkinter", moduleMethods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003194 if (m == NULL)
3195 return;
Guido van Rossum18468821994-06-20 07:49:28 +00003196
Barry Warsawfa701a81997-01-16 00:15:11 +00003197 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003198 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003199 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003200
Guido van Rossum35d43371997-08-02 00:09:09 +00003201 ins_long(d, "READABLE", TCL_READABLE);
3202 ins_long(d, "WRITABLE", TCL_WRITABLE);
3203 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3204 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3205 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3206 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3207 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3208 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3209 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003210 ins_string(d, "TK_VERSION", TK_VERSION);
3211 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003212
Guido van Rossum83551bf1997-09-13 00:44:23 +00003213 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003214
Christian Heimese93237d2007-12-19 02:37:44 +00003215 Py_TYPE(&Tktt_Type) = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003216 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3217
Christian Heimese93237d2007-12-19 02:37:44 +00003218 Py_TYPE(&PyTclObject_Type) = &PyType_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003219 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003220
3221#ifdef TK_AQUA
3222 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3223 * start waking up. Note that Tcl_FindExecutable will do this, this
3224 * code must be above it! The original warning from
3225 * tkMacOSXAppInit.c is copied below.
3226 *
3227 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3228 * Tcl interpreter for now. It probably should work to do this
3229 * in the other order, but for now it doesn't seem to.
3230 *
3231 */
3232 Tk_MacOSXSetupTkNotifier();
3233#endif
3234
3235
Guido van Rossume187b0e2000-03-27 21:46:29 +00003236 /* This helps the dynamic loader; in Unicode aware Tcl versions
3237 it also helps Tcl find its encodings. */
3238 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00003239
Barry Warsawfa701a81997-01-16 00:15:11 +00003240 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003241 return;
3242
Guido van Rossum43ff8681998-07-14 18:02:13 +00003243#if 0
3244 /* This was not a good idea; through <Destroy> bindings,
3245 Tcl_Finalize() may invoke Python code but at that point the
3246 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003247 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003248#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003249
Guido van Rossum18468821994-06-20 07:49:28 +00003250}