blob: ef38ea39620474e3f36940d920cf9d1d9fbc6035 [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 Polo491aee22009-02-06 23:16:11 +000012 Only Tcl/Tk 8.3.1 and later are supported. Older versions are not
13 supported. Use Python 2.6 or older if you cannot upgrade your
14 Tcl/Tk libraries.
Guido van Rossuma80649b2000-03-28 20:07:05 +000015*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000016
Guido van Rossuma80649b2000-03-28 20:07:05 +000017/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000018
Guido van Rossum212643f1998-04-29 16:22:14 +000019 - Register a new Tcl type, "Python callable", which can be called more
20 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
21
Guido van Rossum7ffa7611996-08-13 21:10:16 +000022*/
23
Guido van Rossum35d43371997-08-02 00:09:09 +000024
Guido van Rossum9722ad81995-09-22 23:49:28 +000025#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000026#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000027
Guido van Rossum00d93061998-05-28 23:06:38 +000028#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000029#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000030#endif
31
Guido van Rossum2a5119b1998-05-29 01:28:40 +000032#ifdef MS_WINDOWS
33#include <windows.h>
34#endif
35
Martin v. Löwis39195712003-01-04 00:33:13 +000036/* Allow using this code in Python 2.[12] */
37#ifndef PyDoc_STRVAR
Martin v. Löwiscd9a8b62003-01-21 21:52:57 +000038#define PyDoc_STRVAR(name,str) static char name[] = str
Martin v. Löwis39195712003-01-04 00:33:13 +000039#endif
40
41#ifndef PyMODINIT_FUNC
Martin v. Löwis3a57d9d2003-01-04 08:54:59 +000042#define PyMODINIT_FUNC void
Martin v. Löwis39195712003-01-04 00:33:13 +000043#endif
44
Martin v. Löwis52ae6f62003-03-30 08:26:04 +000045#ifndef PyBool_Check
46#define PyBool_Check(o) 0
Christian Heimes217cfd12007-12-02 14:31:20 +000047#define PyBool_FromLong PyLong_FromLong
Martin v. Löwis52ae6f62003-03-30 08:26:04 +000048#endif
49
Martin v. Löwis71e25a02002-10-01 18:08:06 +000050/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
51 making _tkinter correct for this API means to break earlier
52 versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
53 earlier versions. Once Tcl releases before 8.4 don't need to be supported
54 anymore, this should go. */
55#define USE_COMPAT_CONST
56
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000057/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
58 it always; if Tcl is not threaded, the thread functions in
59 Tcl are empty. */
60#define TCL_THREADS
61
Jack Jansencb852442001-12-09 23:15:56 +000062#ifdef TK_FRAMEWORK
63#include <Tcl/tcl.h>
64#include <Tk/tk.h>
65#else
Guido van Rossum18468821994-06-20 07:49:28 +000066#include <tcl.h>
67#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000068#endif
Guido van Rossum18468821994-06-20 07:49:28 +000069
Guilherme Polo2d87e422009-04-10 22:19:09 +000070#include "tkinter.h"
71
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 Polo66917722009-02-09 22:35:27 +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
Guido van Rossum82c0dfa2007-11-21 20:09:18 +000086 either UTF-16 or UCS-4.
87 Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for
Martin v. Löwis6f29ff32003-04-16 20:34:55 +000088 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 Heimes90aa7642007-12-19 02:45:37 +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 Heimes90aa7642007-12-19 02:45:37 +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 Polob681df42009-02-09 22:33:59 +0000283#ifdef TKINTER_PROTECT_LOADTK
Alexandre Vassalotti21455952009-04-05 01:30:02 +0000284static int tk_load_failed = 0;
Guilherme Polob681df42009-02-09 22:33:59 +0000285#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{
Christian Heimes72b710a2008-05-26 13:28:38 +0000341 if (PyBytes_Check(value))
342 return PyBytes_AsString(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000343 else if (PyUnicode_Check(value)) {
344 PyObject *v = PyUnicode_AsUTF8String(value);
345 if (v == NULL)
346 return NULL;
347 if (PyList_Append(tmp, v) != 0) {
348 Py_DECREF(v);
349 return NULL;
350 }
351 Py_DECREF(v);
Christian Heimes72b710a2008-05-26 13:28:38 +0000352 return PyBytes_AsString(v);
Guido van Rossum2834b972000-10-06 16:58:26 +0000353 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000354 else {
355 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000356 if (v == NULL)
357 return NULL;
358 if (PyList_Append(tmp, v) != 0) {
359 Py_DECREF(v);
360 return NULL;
361 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000362 Py_DECREF(v);
Christian Heimes72b710a2008-05-26 13:28:38 +0000363 return PyBytes_AsString(v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000364 }
Guido van Rossum18468821994-06-20 07:49:28 +0000365}
366
Barry Warsawfa701a81997-01-16 00:15:11 +0000367
368
Guido van Rossum18468821994-06-20 07:49:28 +0000369#define ARGSZ 64
370
371static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000372Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000373{
Barry Warsawfa701a81997-01-16 00:15:11 +0000374 PyObject *tmp = NULL;
375 char *argvStore[ARGSZ];
376 char **argv = NULL;
377 int fvStore[ARGSZ];
378 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000379 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000380 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000381
Barry Warsawfa701a81997-01-16 00:15:11 +0000382 if (!(tmp = PyList_New(0)))
383 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000384
Barry Warsawfa701a81997-01-16 00:15:11 +0000385 argv = argvStore;
386 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000387
Barry Warsawfa701a81997-01-16 00:15:11 +0000388 if (args == NULL)
389 argc = 0;
390
391 else if (!PyTuple_Check(args)) {
392 argc = 1;
393 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000394 if (!(argv[0] = AsString(args, tmp)))
395 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000396 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000397 else {
398 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000399
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000401 argv = (char **)ckalloc(argc * sizeof(char *));
402 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000403 if (argv == NULL || fv == NULL) {
404 PyErr_NoMemory();
405 goto finally;
406 }
407 }
408
409 for (i = 0; i < argc; i++) {
410 PyObject *v = PyTuple_GetItem(args, i);
411 if (PyTuple_Check(v)) {
412 fv[i] = 1;
413 if (!(argv[i] = Merge(v)))
414 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000415 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000416 }
417 else if (v == Py_None) {
418 argc = i;
419 break;
420 }
421 else {
422 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000423 if (!(argv[i] = AsString(v, tmp)))
424 goto finally;
425 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000426 }
427 }
Guido van Rossum18468821994-06-20 07:49:28 +0000428 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000429 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000430 if (res == NULL)
431 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000432
Barry Warsawfa701a81997-01-16 00:15:11 +0000433 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000434 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000435 if (fv[i]) {
436 ckfree(argv[i]);
437 }
438 if (argv != argvStore)
439 ckfree(FREECAST argv);
440 if (fv != fvStore)
441 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000442
Barry Warsawfa701a81997-01-16 00:15:11 +0000443 Py_DECREF(tmp);
444 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000445}
446
Barry Warsawfa701a81997-01-16 00:15:11 +0000447
448
Guido van Rossum18468821994-06-20 07:49:28 +0000449static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000450Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000451{
Barry Warsawfa701a81997-01-16 00:15:11 +0000452 int argc;
453 char **argv;
454 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000455
Barry Warsawfa701a81997-01-16 00:15:11 +0000456 if (list == NULL) {
457 Py_INCREF(Py_None);
458 return Py_None;
459 }
Guido van Rossum18468821994-06-20 07:49:28 +0000460
Guido van Rossum00d93061998-05-28 23:06:38 +0000461 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000462 /* Not a list.
463 * Could be a quoted string containing funnies, e.g. {"}.
464 * Return the string itself.
465 */
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000466 return PyUnicode_FromString(list);
Barry Warsawfa701a81997-01-16 00:15:11 +0000467 }
Guido van Rossum18468821994-06-20 07:49:28 +0000468
Barry Warsawfa701a81997-01-16 00:15:11 +0000469 if (argc == 0)
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000470 v = PyUnicode_FromString("");
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 else if (argc == 1)
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000472 v = PyUnicode_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000473 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000474 int i;
475 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000476
Barry Warsawfa701a81997-01-16 00:15:11 +0000477 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000478 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000479 Py_DECREF(v);
480 v = NULL;
481 break;
482 }
483 PyTuple_SetItem(v, i, w);
484 }
485 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000486 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000487 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000488}
489
Martin v. Löwisffad6332002-11-26 09:28:05 +0000490/* In some cases, Tcl will still return strings that are supposed to be
491 lists. SplitObj walks through a nested tuple, finding string objects that
492 need to be split. */
493
Martin v. Löwis59683e82008-06-13 07:50:45 +0000494static PyObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000495SplitObj(PyObject *arg)
496{
497 if (PyTuple_Check(arg)) {
498 int i, size;
499 PyObject *elem, *newelem, *result;
500
501 size = PyTuple_Size(arg);
502 result = NULL;
503 /* Recursively invoke SplitObj for all tuple items.
504 If this does not return a new object, no action is
505 needed. */
506 for(i = 0; i < size; i++) {
507 elem = PyTuple_GetItem(arg, i);
508 newelem = SplitObj(elem);
509 if (!newelem) {
510 Py_XDECREF(result);
511 return NULL;
512 }
513 if (!result) {
514 int k;
515 if (newelem == elem) {
516 Py_DECREF(newelem);
517 continue;
518 }
519 result = PyTuple_New(size);
520 if (!result)
521 return NULL;
522 for(k = 0; k < i; k++) {
523 elem = PyTuple_GetItem(arg, k);
524 Py_INCREF(elem);
525 PyTuple_SetItem(result, k, elem);
526 }
527 }
528 PyTuple_SetItem(result, i, newelem);
529 }
530 if (result)
531 return result;
532 /* Fall through, returning arg. */
533 }
Christian Heimes72b710a2008-05-26 13:28:38 +0000534 else if (PyBytes_Check(arg)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000535 int argc;
536 char **argv;
Christian Heimes72b710a2008-05-26 13:28:38 +0000537 char *list = PyBytes_AsString(arg);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000538
539 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
540 Py_INCREF(arg);
541 return arg;
542 }
543 Tcl_Free(FREECAST argv);
544 if (argc > 1)
Christian Heimes72b710a2008-05-26 13:28:38 +0000545 return Split(PyBytes_AsString(arg));
Martin v. Löwisffad6332002-11-26 09:28:05 +0000546 /* Fall through, returning arg. */
547 }
548 Py_INCREF(arg);
549 return arg;
550}
Barry Warsawfa701a81997-01-16 00:15:11 +0000551
552
Guido van Rossum18468821994-06-20 07:49:28 +0000553/**** Tkapp Object ****/
554
555#ifndef WITH_APPINIT
556int
Fred Drake509d79a2000-07-08 04:04:38 +0000557Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000558{
David Aschere2b4b322004-02-18 05:59:53 +0000559 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000560
Barry Warsawfa701a81997-01-16 00:15:11 +0000561 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000562 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000563 return TCL_ERROR;
564 }
Guilherme Polob681df42009-02-09 22:33:59 +0000565
566 _tkinter_skip_tk_init = Tcl_GetVar(interp,
567 "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
568 if (_tkinter_skip_tk_init != NULL &&
569 strcmp(_tkinter_skip_tk_init, "1") == 0) {
570 return TCL_OK;
Barry Warsawfa701a81997-01-16 00:15:11 +0000571 }
Guilherme Polob681df42009-02-09 22:33:59 +0000572
573#ifdef TKINTER_PROTECT_LOADTK
574 if (tk_load_failed) {
575 PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG);
576 return TCL_ERROR;
577 }
578#endif
579
580 if (Tk_Init(interp) == TCL_ERROR) {
581#ifdef TKINTER_PROTECT_LOADTK
582 tk_load_failed = 1;
583#endif
584 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
585 return TCL_ERROR;
586 }
587
Barry Warsawfa701a81997-01-16 00:15:11 +0000588 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000589}
590#endif /* !WITH_APPINIT */
591
Guido van Rossum18468821994-06-20 07:49:28 +0000592
Barry Warsawfa701a81997-01-16 00:15:11 +0000593
594
595/* Initialize the Tk application; see the `main' function in
596 * `tkMain.c'.
597 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000598
Thomas Wouters58d05102000-07-24 14:43:35 +0000599static void EnableEventHook(void); /* Forward */
600static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000601
Barry Warsawfa701a81997-01-16 00:15:11 +0000602static TkappObject *
Martin v. Löwisb9279bc2008-04-05 19:47:23 +0000603Tkapp_New(char *screenName, char *className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000604 int interactive, int wantobjects, int wantTk, int sync, char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000605{
606 TkappObject *v;
607 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000608
Guido van Rossumb18618d2000-05-03 23:44:39 +0000609 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000610 if (v == NULL)
611 return NULL;
612
613 v->interp = Tcl_CreateInterp();
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000614 v->wantobjects = wantobjects;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000615 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
616 TCL_GLOBAL_ONLY) != NULL;
617 v->thread_id = Tcl_GetCurrentThread();
618 v->dispatching = 0;
619
620#ifndef TCL_THREADS
621 if (v->threaded) {
622 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
623 Py_DECREF(v);
624 return 0;
625 }
626#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000627#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000628 if (v->threaded && tcl_lock) {
629 /* If Tcl is threaded, we don't need the lock. */
630 PyThread_free_lock(tcl_lock);
631 tcl_lock = NULL;
632 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000633#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000634
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000635 v->BooleanType = Tcl_GetObjType("boolean");
636 v->ByteArrayType = Tcl_GetObjType("bytearray");
637 v->DoubleType = Tcl_GetObjType("double");
638 v->IntType = Tcl_GetObjType("int");
639 v->ListType = Tcl_GetObjType("list");
640 v->ProcBodyType = Tcl_GetObjType("procbody");
641 v->StringType = Tcl_GetObjType("string");
642
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000643 /* Delete the 'exit' command, which can screw things up */
644 Tcl_DeleteCommand(v->interp, "exit");
645
Barry Warsawfa701a81997-01-16 00:15:11 +0000646 if (screenName != NULL)
647 Tcl_SetVar2(v->interp, "env", "DISPLAY",
648 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000649
Barry Warsawfa701a81997-01-16 00:15:11 +0000650 if (interactive)
651 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
652 else
653 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000654
Barry Warsawfa701a81997-01-16 00:15:11 +0000655 /* This is used to get the application class for Tk 4.1 and up */
656 argv0 = (char*)ckalloc(strlen(className) + 1);
657 if (!argv0) {
658 PyErr_NoMemory();
659 Py_DECREF(v);
660 return NULL;
661 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000662
Barry Warsawfa701a81997-01-16 00:15:11 +0000663 strcpy(argv0, className);
Neal Norwitz9dbc7dd2005-12-19 06:08:59 +0000664 if (isupper(Py_CHARMASK(argv0[0])))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000665 argv0[0] = tolower(Py_CHARMASK(argv0[0]));
Barry Warsawfa701a81997-01-16 00:15:11 +0000666 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
667 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000668
David Aschere2b4b322004-02-18 05:59:53 +0000669 if (! wantTk) {
Guilherme Polob681df42009-02-09 22:33:59 +0000670 Tcl_SetVar(v->interp,
671 "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
David Aschere2b4b322004-02-18 05:59:53 +0000672 }
Guilherme Polob681df42009-02-09 22:33:59 +0000673#ifdef TKINTER_PROTECT_LOADTK
674 else if (tk_load_failed) {
675 Tcl_SetVar(v->interp,
676 "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY);
677 }
678#endif
David Aschere2b4b322004-02-18 05:59:53 +0000679
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000680 /* some initial arguments need to be in argv */
681 if (sync || use) {
Tim Peters51fa3b72004-08-04 02:16:48 +0000682 char *args;
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000683 int len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000684
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000685 if (sync)
686 len += sizeof "-sync";
687 if (use)
688 len += strlen(use) + sizeof "-use ";
689
Tim Peters51fa3b72004-08-04 02:16:48 +0000690 args = (char*)ckalloc(len);
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000691 if (!args) {
692 PyErr_NoMemory();
693 Py_DECREF(v);
694 return NULL;
695 }
696
697 args[0] = '\0';
698 if (sync)
699 strcat(args, "-sync");
700 if (use) {
701 if (sync)
702 strcat(args, " ");
703 strcat(args, "-use ");
704 strcat(args, use);
705 }
706
707 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
708 ckfree(args);
709 }
710
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000711 if (Tcl_AppInit(v->interp) != TCL_OK) {
712 PyObject *result = Tkinter_Error((PyObject *)v);
Guilherme Polob681df42009-02-09 22:33:59 +0000713#ifdef TKINTER_PROTECT_LOADTK
714 if (wantTk) {
715 const char *_tkinter_tk_failed;
716 _tkinter_tk_failed = Tcl_GetVar(v->interp,
717 "_tkinter_tk_failed", TCL_GLOBAL_ONLY);
718
719 if ( _tkinter_tk_failed != NULL &&
720 strcmp(_tkinter_tk_failed, "1") == 0) {
721 tk_load_failed = 1;
722 }
723 }
724#endif
Thomas Woutersa74a84d2006-03-07 14:04:31 +0000725 Py_DECREF((PyObject *)v);
726 return (TkappObject *)result;
727 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000728
Guido van Rossum7bf15641998-05-22 18:28:17 +0000729 EnableEventHook();
730
Barry Warsawfa701a81997-01-16 00:15:11 +0000731 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000732}
733
Barry Warsawfa701a81997-01-16 00:15:11 +0000734
Benjamin Peterson5879d412009-03-30 14:51:56 +0000735#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000736static void
737Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
738 Tcl_Condition *cond, Tcl_Mutex *mutex)
739{
740 Py_BEGIN_ALLOW_THREADS;
741 Tcl_MutexLock(mutex);
742 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
743 Tcl_ThreadAlert(self->thread_id);
744 Tcl_ConditionWait(cond, mutex, NULL);
745 Tcl_MutexUnlock(mutex);
746 Py_END_ALLOW_THREADS
747}
Benjamin Peterson5879d412009-03-30 14:51:56 +0000748#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000749
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
Neal Norwitz227b5332006-03-22 09:28:35 +0000759static PyTypeObject PyTclObject_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000760#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
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000783static char*
784PyTclObject_TclString(PyObject *self)
785{
786 return Tcl_GetString(((PyTclObject*)self)->value);
787}
788
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000789/* Like _str, but create Unicode if necessary. */
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000790PyDoc_STRVAR(PyTclObject_string__doc__,
Christian Heimesb2b62622007-11-22 05:56:35 +0000791"the string representation of this object, either as str or bytes");
Martin v. Löwis39195712003-01-04 00:33:13 +0000792
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000793static PyObject *
794PyTclObject_string(PyTclObject *self, void *ignored)
795{
796 char *s;
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000797 int len;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000798 if (!self->string) {
799 s = Tcl_GetStringFromObj(self->value, &len);
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000800 self->string = PyUnicode_FromStringAndSize(s, len);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000801 if (!self->string)
802 return NULL;
803 }
804 Py_INCREF(self->string);
805 return self->string;
806}
807
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000808static PyObject *
Walter Dörwald6720d912007-07-12 12:12:25 +0000809PyTclObject_str(PyTclObject *self, void *ignored)
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000810{
811 char *s;
812 int len;
813 if (self->string && PyUnicode_Check(self->string)) {
814 Py_INCREF(self->string);
815 return self->string;
816 }
817 /* XXX Could chache result if it is non-ASCII. */
818 s = Tcl_GetStringFromObj(self->value, &len);
819 return PyUnicode_DecodeUTF8(s, len, "strict");
820}
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000821
Martin v. Löwisffad6332002-11-26 09:28:05 +0000822static PyObject *
823PyTclObject_repr(PyTclObject *self)
824{
Walter Dörwald7569dfe2007-05-19 21:49:49 +0000825 return PyUnicode_FromFormat("<%s object at %p>",
826 self->value->typePtr->name, self->value);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000827}
828
Mark Dickinson211c6252009-02-01 10:28:51 +0000829#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
830
831static PyObject *
832PyTclObject_richcompare(PyObject *self, PyObject *other, int op)
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000833{
Mark Dickinson211c6252009-02-01 10:28:51 +0000834 int result;
835 PyObject *v;
836
837 /* neither argument should be NULL, unless something's gone wrong */
838 if (self == NULL || other == NULL) {
839 PyErr_BadInternalCall();
840 return NULL;
841 }
842
843 /* both arguments should be instances of PyTclObject */
844 if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) {
845 v = Py_NotImplemented;
846 goto finished;
847 }
848
849 if (self == other)
850 /* fast path when self and other are identical */
851 result = 0;
852 else
853 result = strcmp(Tcl_GetString(((PyTclObject *)self)->value),
854 Tcl_GetString(((PyTclObject *)other)->value));
855 /* Convert return value to a Boolean */
856 switch (op) {
857 case Py_EQ:
858 v = TEST_COND(result == 0);
859 break;
860 case Py_NE:
861 v = TEST_COND(result != 0);
862 break;
863 case Py_LE:
864 v = TEST_COND(result <= 0);
865 break;
866 case Py_GE:
867 v = TEST_COND(result >= 0);
868 break;
869 case Py_LT:
870 v = TEST_COND(result < 0);
871 break;
872 case Py_GT:
873 v = TEST_COND(result > 0);
874 break;
875 default:
876 PyErr_BadArgument();
877 return NULL;
878 }
879 finished:
880 Py_INCREF(v);
881 return v;
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000882}
883
Martin v. Löwis39195712003-01-04 00:33:13 +0000884PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
885
Martin v. Löwisffad6332002-11-26 09:28:05 +0000886static PyObject*
887get_typename(PyTclObject* obj, void* ignored)
888{
Martin v. Löwis4040fb82007-08-13 06:01:43 +0000889 return PyUnicode_FromString(obj->value->typePtr->name);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000890}
891
Martin v. Löwis39195712003-01-04 00:33:13 +0000892
Martin v. Löwisffad6332002-11-26 09:28:05 +0000893static PyGetSetDef PyTclObject_getsetlist[] = {
Martin v. Löwis39195712003-01-04 00:33:13 +0000894 {"typename", (getter)get_typename, NULL, get_typename__doc__},
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000895 {"string", (getter)PyTclObject_string, NULL,
Martin v. Löwis39195712003-01-04 00:33:13 +0000896 PyTclObject_string__doc__},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000897 {0},
898};
899
Neal Norwitz227b5332006-03-22 09:28:35 +0000900static PyTypeObject PyTclObject_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000901 PyVarObject_HEAD_INIT(NULL, 0)
Martin v. Löwisffad6332002-11-26 09:28:05 +0000902 "_tkinter.Tcl_Obj", /*tp_name*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000903 sizeof(PyTclObject), /*tp_basicsize*/
904 0, /*tp_itemsize*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000905 /* methods */
Mark Dickinson211c6252009-02-01 10:28:51 +0000906 (destructor)PyTclObject_dealloc,/*tp_dealloc*/
907 0, /*tp_print*/
908 0, /*tp_getattr*/
909 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000910 0, /*tp_reserved*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000911 (reprfunc)PyTclObject_repr, /*tp_repr*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000912 0, /*tp_as_number*/
913 0, /*tp_as_sequence*/
914 0, /*tp_as_mapping*/
915 0, /*tp_hash*/
916 0, /*tp_call*/
917 (reprfunc)PyTclObject_str, /*tp_str*/
918 PyObject_GenericGetAttr, /*tp_getattro*/
919 0, /*tp_setattro*/
920 0, /*tp_as_buffer*/
921 Py_TPFLAGS_DEFAULT, /*tp_flags*/
922 0, /*tp_doc*/
923 0, /*tp_traverse*/
924 0, /*tp_clear*/
925 PyTclObject_richcompare, /*tp_richcompare*/
926 0, /*tp_weaklistoffset*/
927 0, /*tp_iter*/
928 0, /*tp_iternext*/
929 0, /*tp_methods*/
930 0, /*tp_members*/
931 PyTclObject_getsetlist, /*tp_getset*/
932 0, /*tp_base*/
933 0, /*tp_dict*/
934 0, /*tp_descr_get*/
935 0, /*tp_descr_set*/
936 0, /*tp_dictoffset*/
937 0, /*tp_init*/
938 0, /*tp_alloc*/
939 0, /*tp_new*/
940 0, /*tp_free*/
941 0, /*tp_is_gc*/
Martin v. Löwisffad6332002-11-26 09:28:05 +0000942};
943
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000944static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000945AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000946{
947 Tcl_Obj *result;
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +0000948 long longVal;
949 int overflow;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000950
Christian Heimes72b710a2008-05-26 13:28:38 +0000951 if (PyBytes_Check(value))
952 return Tcl_NewStringObj(PyBytes_AS_STRING(value),
953 PyBytes_GET_SIZE(value));
Martin v. Löwis70c3dda2003-01-22 09:17:38 +0000954 else if (PyBool_Check(value))
955 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +0000956 else if (PyLong_CheckExact(value) &&
957 ((longVal = PyLong_AsLongAndOverflow(value, &overflow)),
958 !overflow)) {
959 /* If there is an overflow in the long conversion,
960 fall through to default object handling. */
961 return Tcl_NewLongObj(longVal);
962 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000963 else if (PyFloat_Check(value))
964 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
965 else if (PyTuple_Check(value)) {
966 Tcl_Obj **argv = (Tcl_Obj**)
967 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
968 int i;
969 if(!argv)
970 return 0;
971 for(i=0;i<PyTuple_Size(value);i++)
972 argv[i] = AsObj(PyTuple_GetItem(value,i));
973 result = Tcl_NewListObj(PyTuple_Size(value), argv);
974 ckfree(FREECAST argv);
975 return result;
976 }
977 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000978 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000979 Py_ssize_t size = PyUnicode_GET_SIZE(value);
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000980 /* This #ifdef assumes that Tcl uses UCS-2.
981 See TCL_UTF_MAX test above. */
Martin v. Löwis6f29ff32003-04-16 20:34:55 +0000982#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
Christian Heimesa34706f2008-01-04 03:06:10 +0000983 Tcl_UniChar *outbuf = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000984 Py_ssize_t i;
Christian Heimesa34706f2008-01-04 03:06:10 +0000985 size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
986 if (allocsize >= size)
987 outbuf = (Tcl_UniChar*)ckalloc(allocsize);
988 /* Else overflow occurred, and we take the next exit */
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000989 if (!outbuf) {
990 PyErr_NoMemory();
991 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000992 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000993 for (i = 0; i < size; i++) {
994 if (inbuf[i] >= 0x10000) {
995 /* Tcl doesn't do UTF-16, yet. */
996 PyErr_SetString(PyExc_ValueError,
997 "unsupported character");
998 ckfree(FREECAST outbuf);
999 return NULL;
1000 }
1001 outbuf[i] = inbuf[i];
1002 }
1003 result = Tcl_NewUnicodeObj(outbuf, size);
1004 ckfree(FREECAST outbuf);
1005 return result;
1006#else
1007 return Tcl_NewUnicodeObj(inbuf, size);
1008#endif
1009
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001010 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001011 else if(PyTclObject_Check(value)) {
1012 Tcl_Obj *v = ((PyTclObject*)value)->value;
1013 Tcl_IncrRefCount(v);
1014 return v;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001015 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001016 else {
1017 PyObject *v = PyObject_Str(value);
1018 if (!v)
1019 return 0;
1020 result = AsObj(v);
1021 Py_DECREF(v);
1022 return result;
1023 }
1024}
1025
Martin v. Löwisffad6332002-11-26 09:28:05 +00001026static PyObject*
1027FromObj(PyObject* tkapp, Tcl_Obj *value)
1028{
1029 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001030 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +00001031
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001032 if (value->typePtr == NULL) {
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001033 return PyUnicode_FromStringAndSize(value->bytes,
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001034 value->length);
Martin v. Löwise07e18d2002-12-04 19:54:36 +00001035 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001036
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001037 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001038 result = value->internalRep.longValue ? Py_True : Py_False;
1039 Py_INCREF(result);
1040 return result;
1041 }
1042
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001043 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001044 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +00001045 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Christian Heimes72b710a2008-05-26 13:28:38 +00001046 return PyBytes_FromStringAndSize(data, size);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001047 }
1048
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001049 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001050 return PyFloat_FromDouble(value->internalRep.doubleValue);
1051 }
1052
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001053 if (value->typePtr == app->IntType) {
Christian Heimes217cfd12007-12-02 14:31:20 +00001054 return PyLong_FromLong(value->internalRep.longValue);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001055 }
1056
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001057 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001058 int size;
1059 int i, status;
1060 PyObject *elem;
1061 Tcl_Obj *tcl_elem;
1062
1063 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
1064 if (status == TCL_ERROR)
1065 return Tkinter_Error(tkapp);
1066 result = PyTuple_New(size);
1067 if (!result)
1068 return NULL;
1069 for (i = 0; i < size; i++) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001070 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
Martin v. Löwisffad6332002-11-26 09:28:05 +00001071 value, i, &tcl_elem);
1072 if (status == TCL_ERROR) {
1073 Py_DECREF(result);
1074 return Tkinter_Error(tkapp);
1075 }
1076 elem = FromObj(tkapp, tcl_elem);
1077 if (!elem) {
1078 Py_DECREF(result);
1079 return NULL;
1080 }
1081 PyTuple_SetItem(result, i, elem);
1082 }
1083 return result;
1084 }
1085
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001086 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001087 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +00001088 }
1089
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00001090 if (value->typePtr == app->StringType) {
Martin v. Löwis6f29ff32003-04-16 20:34:55 +00001091#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
Martin v. Löwisffad6332002-11-26 09:28:05 +00001092 PyObject *result;
1093 int size;
1094 Tcl_UniChar *input;
1095 Py_UNICODE *output;
1096
1097 size = Tcl_GetCharLength(value);
1098 result = PyUnicode_FromUnicode(NULL, size);
1099 if (!result)
1100 return NULL;
1101 input = Tcl_GetUnicode(value);
1102 output = PyUnicode_AS_UNICODE(result);
1103 while (size--)
1104 *output++ = *input++;
1105 return result;
1106#else
1107 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1108 Tcl_GetCharLength(value));
1109#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +00001110 }
1111
1112 return newPyTclObject(value);
1113}
1114
Benjamin Peterson5879d412009-03-30 14:51:56 +00001115#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001116/* This mutex synchronizes inter-thread command calls. */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001117TCL_DECLARE_MUTEX(call_mutex)
1118
1119typedef struct Tkapp_CallEvent {
1120 Tcl_Event ev; /* Must be first */
1121 TkappObject *self;
1122 PyObject *args;
1123 int flags;
1124 PyObject **res;
1125 PyObject **exc_type, **exc_value, **exc_tb;
Guilherme Polo491aee22009-02-06 23:16:11 +00001126 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001127} Tkapp_CallEvent;
Benjamin Peterson5879d412009-03-30 14:51:56 +00001128#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001129
1130void
1131Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001132{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001133 int i;
1134 for (i = 0; i < objc; i++)
1135 Tcl_DecrRefCount(objv[i]);
1136 if (objv != objStore)
1137 ckfree(FREECAST objv);
1138}
Guido van Rossum18468821994-06-20 07:49:28 +00001139
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001140/* Convert Python objects to Tcl objects. This must happen in the
1141 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001142
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001143static Tcl_Obj**
1144Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1145{
1146 Tcl_Obj **objv = objStore;
Martin v. Löwis7d134952002-12-12 19:05:48 +00001147 int objc = 0, i;
Guido van Rossum212643f1998-04-29 16:22:14 +00001148 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +00001149 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001150
Guido van Rossum212643f1998-04-29 16:22:14 +00001151 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +00001152 objv[0] = AsObj(args);
1153 if (objv[0] == 0)
1154 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001155 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +00001156 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001157 }
1158 else {
Guido van Rossum632de272000-03-29 00:19:50 +00001159 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001160
Guido van Rossum632de272000-03-29 00:19:50 +00001161 if (objc > ARGSZ) {
1162 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1163 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001164 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +00001165 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +00001166 goto finally;
1167 }
1168 }
1169
Guido van Rossum632de272000-03-29 00:19:50 +00001170 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +00001171 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +00001172 if (v == Py_None) {
1173 objc = i;
1174 break;
1175 }
Guido van Rossum632de272000-03-29 00:19:50 +00001176 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +00001177 if (!objv[i]) {
1178 /* Reset objc, so it attempts to clear
1179 objects only up to i. */
1180 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +00001181 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +00001182 }
Guido van Rossum632de272000-03-29 00:19:50 +00001183 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +00001184 }
1185 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001186 *pobjc = objc;
1187 return objv;
1188finally:
1189 Tkapp_CallDeallocArgs(objv, objStore, objc);
1190 return NULL;
1191}
Guido van Rossum212643f1998-04-29 16:22:14 +00001192
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001193/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001194
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001195static PyObject*
1196Tkapp_CallResult(TkappObject *self)
1197{
1198 PyObject *res = NULL;
1199 if(self->wantobjects) {
1200 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001201 /* Not sure whether the IncrRef is necessary, but something
1202 may overwrite the interpreter result while we are
1203 converting it. */
1204 Tcl_IncrRefCount(value);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001205 res = FromObj((PyObject*)self, value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001206 Tcl_DecrRefCount(value);
1207 } else {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001208 const char *s = Tcl_GetStringResult(self->interp);
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001209 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001210
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001211 res = PyUnicode_FromStringAndSize(s, (int)(p-s));
Guido van Rossum990f5c62000-05-04 15:07:16 +00001212 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001213 return res;
1214}
Guido van Rossum632de272000-03-29 00:19:50 +00001215
Benjamin Peterson5879d412009-03-30 14:51:56 +00001216#ifdef WITH_THREAD
1217
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001218/* Tkapp_CallProc is the event procedure that is executed in the context of
1219 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1220 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001221
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001222static int
1223Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1224{
1225 Tcl_Obj *objStore[ARGSZ];
1226 Tcl_Obj **objv;
1227 int objc;
1228 int i;
1229 ENTER_PYTHON
1230 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1231 if (!objv) {
1232 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1233 *(e->res) = NULL;
1234 }
1235 LEAVE_PYTHON
1236 if (!objv)
1237 goto done;
1238 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1239 ENTER_PYTHON
1240 if (i == TCL_ERROR) {
1241 *(e->res) = NULL;
1242 *(e->exc_type) = NULL;
1243 *(e->exc_tb) = NULL;
1244 *(e->exc_value) = PyObject_CallFunction(
1245 Tkinter_TclError, "s",
1246 Tcl_GetStringResult(e->self->interp));
1247 }
1248 else {
1249 *(e->res) = Tkapp_CallResult(e->self);
1250 }
1251 LEAVE_PYTHON
Guilherme Polo491aee22009-02-06 23:16:11 +00001252
1253 Tkapp_CallDeallocArgs(objv, objStore, objc);
1254done:
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001255 /* Wake up calling thread. */
1256 Tcl_MutexLock(&call_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00001257 Tcl_ConditionNotify(e->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001258 Tcl_MutexUnlock(&call_mutex);
1259 return 1;
1260}
1261
Benjamin Peterson5879d412009-03-30 14:51:56 +00001262#endif
1263
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001264/* This is the main entry point for calling a Tcl command.
1265 It supports three cases, with regard to threading:
1266 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1267 the context of the calling thread.
1268 2. Tcl is threaded, caller of the command is in the interpreter thread:
1269 Execute the command in the calling thread. Since the Tcl lock will
1270 not be used, we can merge that with case 1.
1271 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1272 the interpreter thread. Allocation of Tcl objects needs to occur in the
1273 interpreter thread, so we ship the PyObject* args to the target thread,
1274 and perform processing there. */
1275
1276static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001277Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001278{
1279 Tcl_Obj *objStore[ARGSZ];
1280 Tcl_Obj **objv = NULL;
1281 int objc, i;
1282 PyObject *res = NULL;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001283 TkappObject *self = (TkappObject*)selfptr;
Guilherme Polo7f423952009-02-02 21:17:09 +00001284 int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001285
Guido van Rossum992d4a32007-07-11 13:09:30 +00001286 /* If args is a single tuple, replace with contents of tuple */
1287 if (1 == PyTuple_Size(args)){
1288 PyObject* item = PyTuple_GetItem(args, 0);
1289 if (PyTuple_Check(item))
1290 args = item;
1291 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001292#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001293 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1294 /* We cannot call the command directly. Instead, we must
1295 marshal the parameters to the interpreter thread. */
1296 Tkapp_CallEvent *ev;
Guilherme Polo491aee22009-02-06 23:16:11 +00001297 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001298 PyObject *exc_type, *exc_value, *exc_tb;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001299 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001300 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001301 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1302 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1303 ev->self = self;
1304 ev->args = args;
1305 ev->res = &res;
1306 ev->exc_type = &exc_type;
1307 ev->exc_value = &exc_value;
1308 ev->exc_tb = &exc_tb;
Guilherme Polo491aee22009-02-06 23:16:11 +00001309 ev->done = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001310
Guilherme Polo491aee22009-02-06 23:16:11 +00001311 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001312
1313 if (res == NULL) {
1314 if (exc_type)
1315 PyErr_Restore(exc_type, exc_value, exc_tb);
1316 else
1317 PyErr_SetObject(Tkinter_TclError, exc_value);
1318 }
Guilherme Polo491aee22009-02-06 23:16:11 +00001319 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001320 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001321 else
Martin v. Löwisa9656492003-03-30 08:44:58 +00001322#endif
1323 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001324
1325 objv = Tkapp_CallArgs(args, objStore, &objc);
1326 if (!objv)
1327 return NULL;
1328
1329 ENTER_TCL
1330
1331 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1332
1333 ENTER_OVERLAP
1334
1335 if (i == TCL_ERROR)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001336 Tkinter_Error(selfptr);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001337 else
1338 res = Tkapp_CallResult(self);
1339
1340 LEAVE_OVERLAP_TCL
1341
1342 Tkapp_CallDeallocArgs(objv, objStore, objc);
1343 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001344 return res;
1345}
1346
1347
1348static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001349Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001350{
Guido van Rossum212643f1998-04-29 16:22:14 +00001351 /* Could do the same here as for Tkapp_Call(), but this is not used
1352 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1353 way for the user to do what all its Global* variants do (save and
1354 reset the scope pointer, call the local version, restore the saved
1355 scope pointer). */
1356
Guido van Rossum62320c91998-06-15 04:36:09 +00001357 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001358 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001359
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001360 CHECK_TCL_APPARTMENT;
1361
Guido van Rossum62320c91998-06-15 04:36:09 +00001362 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001363 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001364 int err;
1365 ENTER_TCL
1366 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001367 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001368 if (err == TCL_ERROR)
1369 res = Tkinter_Error(self);
1370 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001371 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001372 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001373 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001374 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001375
1376 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001377}
1378
1379static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001380Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001381{
Barry Warsawfa701a81997-01-16 00:15:11 +00001382 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001383 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001384 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001385
Guido van Rossum43713e52000-02-29 13:59:29 +00001386 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001387 return NULL;
1388
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001389 CHECK_TCL_APPARTMENT;
1390
Guido van Rossum00d93061998-05-28 23:06:38 +00001391 ENTER_TCL
1392 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001393 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001394 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001395 res = Tkinter_Error(self);
1396 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001397 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001398 LEAVE_OVERLAP_TCL
1399 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001400}
1401
1402static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001403Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001404{
Barry Warsawfa701a81997-01-16 00:15:11 +00001405 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001406 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001407 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001408
Guido van Rossum43713e52000-02-29 13:59:29 +00001409 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001410 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001411
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001412 CHECK_TCL_APPARTMENT;
1413
Guido van Rossum00d93061998-05-28 23:06:38 +00001414 ENTER_TCL
1415 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001416 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001417 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001418 res = Tkinter_Error(self);
1419 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001420 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001421 LEAVE_OVERLAP_TCL
1422 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001423}
1424
1425static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001426Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001427{
Barry Warsawfa701a81997-01-16 00:15:11 +00001428 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001429 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001430 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001431
Guido van Rossum43713e52000-02-29 13:59:29 +00001432 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001433 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001434
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001435 CHECK_TCL_APPARTMENT;
1436
Guido van Rossum00d93061998-05-28 23:06:38 +00001437 ENTER_TCL
1438 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001439 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001440 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001441 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001442
Guido van Rossum62320c91998-06-15 04:36:09 +00001443 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001444 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001445 LEAVE_OVERLAP_TCL
1446 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001447}
1448
1449static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001450Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001451{
Barry Warsawfa701a81997-01-16 00:15:11 +00001452 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001453 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001454 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001455
Guido van Rossum35d43371997-08-02 00:09:09 +00001456 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001457 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001458
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001459 CHECK_TCL_APPARTMENT;
1460
Guido van Rossum00d93061998-05-28 23:06:38 +00001461 ENTER_TCL
1462 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001463 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001464 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001465 res = Tkinter_Error(self);
1466 else
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001467 res = PyUnicode_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001468 LEAVE_OVERLAP_TCL
1469 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001470}
1471
1472static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001473Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001474{
Barry Warsawfa701a81997-01-16 00:15:11 +00001475 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001476
Guido van Rossum43713e52000-02-29 13:59:29 +00001477 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001478 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001479 CHECK_TCL_APPARTMENT;
1480
Guido van Rossum00d93061998-05-28 23:06:38 +00001481 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001482 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001483 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001484
Barry Warsawfa701a81997-01-16 00:15:11 +00001485 Py_INCREF(Py_None);
1486 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001487}
1488
Barry Warsawfa701a81997-01-16 00:15:11 +00001489
1490
Guido van Rossum18468821994-06-20 07:49:28 +00001491/** Tcl Variable **/
1492
Benjamin Peterson5879d412009-03-30 14:51:56 +00001493typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
1494
1495#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001496TCL_DECLARE_MUTEX(var_mutex)
1497
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001498typedef struct VarEvent {
1499 Tcl_Event ev; /* must be first */
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001500 PyObject *self;
1501 PyObject *args;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001502 int flags;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001503 EventFunc func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001504 PyObject **res;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001505 PyObject **exc_type;
1506 PyObject **exc_val;
Guilherme Polo491aee22009-02-06 23:16:11 +00001507 Tcl_Condition *cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001508} VarEvent;
Benjamin Peterson5879d412009-03-30 14:51:56 +00001509#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001510
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001511static int
1512varname_converter(PyObject *in, void *_out)
1513{
1514 char **out = (char**)_out;
Christian Heimes72b710a2008-05-26 13:28:38 +00001515 if (PyBytes_Check(in)) {
1516 *out = PyBytes_AsString(in);
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001517 return 1;
1518 }
Guido van Rossumf761e102007-07-23 18:34:37 +00001519 if (PyUnicode_Check(in)) {
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00001520 *out = _PyUnicode_AsString(in);
Guido van Rossumf761e102007-07-23 18:34:37 +00001521 return 1;
1522 }
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001523 if (PyTclObject_Check(in)) {
1524 *out = PyTclObject_TclString(in);
1525 return 1;
1526 }
1527 /* XXX: Should give diagnostics. */
1528 return 0;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001529}
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001530
Benjamin Peterson5879d412009-03-30 14:51:56 +00001531#ifdef WITH_THREAD
1532
Martin v. Löwis59683e82008-06-13 07:50:45 +00001533static void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001534var_perform(VarEvent *ev)
1535{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001536 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1537 if (!*(ev->res)) {
1538 PyObject *exc, *val, *tb;
1539 PyErr_Fetch(&exc, &val, &tb);
1540 PyErr_NormalizeException(&exc, &val, &tb);
1541 *(ev->exc_type) = exc;
1542 *(ev->exc_val) = val;
1543 Py_DECREF(tb);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001544 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001545
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001546}
1547
1548static int
1549var_proc(VarEvent* ev, int flags)
1550{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001551 ENTER_PYTHON
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001552 var_perform(ev);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001553 Tcl_MutexLock(&var_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00001554 Tcl_ConditionNotify(ev->cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001555 Tcl_MutexUnlock(&var_mutex);
1556 LEAVE_PYTHON
1557 return 1;
1558}
1559
Benjamin Peterson5879d412009-03-30 14:51:56 +00001560#endif
1561
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001562static PyObject*
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001563var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001564{
Martin v. Löwisa9656492003-03-30 08:44:58 +00001565#ifdef WITH_THREAD
Benjamin Peterson5879d412009-03-30 14:51:56 +00001566 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001567 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001568 TkappObject *self = (TkappObject*)selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001569 VarEvent *ev;
1570 PyObject *res, *exc_type, *exc_val;
Guilherme Polo491aee22009-02-06 23:16:11 +00001571 Tcl_Condition cond = NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001572
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001573 /* The current thread is not the interpreter thread. Marshal
1574 the call to the interpreter thread, then wait for
1575 completion. */
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00001576 if (!WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001577 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001578
1579 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1580
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001581 ev->self = selfptr;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001582 ev->args = args;
1583 ev->flags = flags;
1584 ev->func = func;
1585 ev->res = &res;
1586 ev->exc_type = &exc_type;
1587 ev->exc_val = &exc_val;
Guilherme Polo491aee22009-02-06 23:16:11 +00001588 ev->cond = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001589 ev->ev.proc = (Tcl_EventProc*)var_proc;
Guilherme Polo491aee22009-02-06 23:16:11 +00001590 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
1591 Tcl_ConditionFinalize(&cond);
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001592 if (!res) {
1593 PyErr_SetObject(exc_type, exc_val);
1594 Py_DECREF(exc_type);
1595 Py_DECREF(exc_val);
1596 return NULL;
1597 }
1598 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001599 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001600#endif
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001601 /* Tcl is not threaded, or this is the interpreter thread. */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001602 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001603}
1604
Guido van Rossum18468821994-06-20 07:49:28 +00001605static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001606SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001607{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001608 char *name1, *name2;
Barry Warsawfa701a81997-01-16 00:15:11 +00001609 PyObject *newValue;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001610 PyObject *res = NULL;
1611 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001612
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001613 if (PyArg_ParseTuple(args, "O&O:setvar",
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001614 varname_converter, &name1, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001615 /* XXX Acquire tcl lock??? */
1616 newval = AsObj(newValue);
1617 if (newval == NULL)
Guido van Rossum2834b972000-10-06 16:58:26 +00001618 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001619 ENTER_TCL
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001620 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001621 newval, flags);
1622 ENTER_OVERLAP
1623 if (!ok)
1624 Tkinter_Error(self);
1625 else {
1626 res = Py_None;
1627 Py_INCREF(res);
1628 }
1629 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001630 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001631 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001632 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001633 if (PyArg_ParseTuple(args, "ssO:setvar",
1634 &name1, &name2, &newValue)) {
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001635 /* XXX must hold tcl lock already??? */
1636 newval = AsObj(newValue);
1637 ENTER_TCL
1638 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1639 ENTER_OVERLAP
1640 if (!ok)
1641 Tkinter_Error(self);
1642 else {
1643 res = Py_None;
1644 Py_INCREF(res);
1645 }
1646 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +00001647 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001648 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001649 return NULL;
1650 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001651 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001652 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001653}
1654
1655static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001656Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001657{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001658 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001659}
1660
1661static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001662Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001663{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001664 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001665}
1666
Barry Warsawfa701a81997-01-16 00:15:11 +00001667
1668
Guido van Rossum18468821994-06-20 07:49:28 +00001669static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001670GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001671{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001672 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001673 PyObject *res = NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001674 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001675
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001676 if (!PyArg_ParseTuple(args, "O&|s:getvar",
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001677 varname_converter, &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001678 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001679
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001680 ENTER_TCL
1681 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1682 ENTER_OVERLAP
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001683 if (tres == NULL) {
1684 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1685 } else {
1686 if (((TkappObject*)self)->wantobjects) {
1687 res = FromObj(self, tres);
1688 }
1689 else {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001690 res = PyUnicode_FromString(Tcl_GetString(tres));
Martin v. Löwisd46e6842003-10-03 17:12:26 +00001691 }
Martin v. Löwis8fd86cc2003-05-19 19:57:42 +00001692 }
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001693 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001694 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001695}
1696
1697static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001698Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001699{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001700 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001701}
1702
1703static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001704Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001705{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001706 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001707}
1708
Barry Warsawfa701a81997-01-16 00:15:11 +00001709
1710
Guido van Rossum18468821994-06-20 07:49:28 +00001711static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001712UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001713{
Guido van Rossum35d43371997-08-02 00:09:09 +00001714 char *name1, *name2=NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001715 int code;
Guido van Rossum62320c91998-06-15 04:36:09 +00001716 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001717
Guido van Rossum43713e52000-02-29 13:59:29 +00001718 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001719 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001720
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001721 ENTER_TCL
1722 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1723 ENTER_OVERLAP
1724 if (code == TCL_ERROR)
1725 res = Tkinter_Error(self);
1726 else {
1727 Py_INCREF(Py_None);
1728 res = Py_None;
1729 }
1730 LEAVE_OVERLAP_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +00001731 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001732}
1733
1734static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001735Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001736{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001737 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001738}
1739
1740static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001741Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001742{
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001743 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001744}
1745
Barry Warsawfa701a81997-01-16 00:15:11 +00001746
1747
Guido van Rossum18468821994-06-20 07:49:28 +00001748/** Tcl to Python **/
1749
1750static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001751Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001752{
Barry Warsawfa701a81997-01-16 00:15:11 +00001753 char *s;
1754 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001755
Martin v. Löwisffad6332002-11-26 09:28:05 +00001756 if (PyTuple_Size(args) == 1) {
1757 PyObject* o = PyTuple_GetItem(args, 0);
Christian Heimes217cfd12007-12-02 14:31:20 +00001758 if (PyLong_Check(o)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001759 Py_INCREF(o);
1760 return o;
1761 }
1762 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001763 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001764 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001765 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001766 return Tkinter_Error(self);
1767 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001768}
1769
1770static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001771Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001772{
Barry Warsawfa701a81997-01-16 00:15:11 +00001773 char *s;
1774 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001775
Martin v. Löwisffad6332002-11-26 09:28:05 +00001776 if (PyTuple_Size(args) == 1) {
1777 PyObject *o = PyTuple_GetItem(args, 0);
1778 if (PyFloat_Check(o)) {
1779 Py_INCREF(o);
1780 return o;
1781 }
1782 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001783 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001784 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001785 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001786 return Tkinter_Error(self);
1787 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001788}
1789
1790static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001791Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001792{
Barry Warsawfa701a81997-01-16 00:15:11 +00001793 char *s;
1794 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001795
Martin v. Löwisffad6332002-11-26 09:28:05 +00001796 if (PyTuple_Size(args) == 1) {
1797 PyObject *o = PyTuple_GetItem(args, 0);
Christian Heimes217cfd12007-12-02 14:31:20 +00001798 if (PyLong_Check(o)) {
Martin v. Löwisffad6332002-11-26 09:28:05 +00001799 Py_INCREF(o);
1800 return o;
1801 }
1802 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001803 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001804 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001805 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1806 return Tkinter_Error(self);
Martin v. Löwis70c3dda2003-01-22 09:17:38 +00001807 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001808}
1809
1810static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001811Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001812{
Barry Warsawfa701a81997-01-16 00:15:11 +00001813 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001814 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001815 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001816
Guido van Rossum43713e52000-02-29 13:59:29 +00001817 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001818 return NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001819
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001820 CHECK_TCL_APPARTMENT;
1821
Guido van Rossum00d93061998-05-28 23:06:38 +00001822 ENTER_TCL
1823 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001824 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001825 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001826 res = Tkinter_Error(self);
1827 else
1828 res = Py_BuildValue("s", Tkapp_Result(self));
1829 LEAVE_OVERLAP_TCL
1830 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001831}
1832
1833static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001834Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001835{
Barry Warsawfa701a81997-01-16 00:15:11 +00001836 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001837 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001838 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001839 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001840
Guido van Rossum43713e52000-02-29 13:59:29 +00001841 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001842 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001843
1844 CHECK_TCL_APPARTMENT;
1845
Guido van Rossum00d93061998-05-28 23:06:38 +00001846 ENTER_TCL
1847 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001848 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001849 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001850 res = Tkinter_Error(self);
1851 else
1852 res = Py_BuildValue("l", v);
1853 LEAVE_OVERLAP_TCL
1854 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001855}
1856
1857static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001858Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001859{
Barry Warsawfa701a81997-01-16 00:15:11 +00001860 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001861 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001862 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001863 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001864
Guido van Rossum43713e52000-02-29 13:59:29 +00001865 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001866 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001867 CHECK_TCL_APPARTMENT;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001868 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001869 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001870 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001871 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001872 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001873 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001874 res = Tkinter_Error(self);
1875 else
1876 res = Py_BuildValue("d", v);
1877 LEAVE_OVERLAP_TCL
1878 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001879}
1880
1881static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001882Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001883{
Barry Warsawfa701a81997-01-16 00:15:11 +00001884 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001885 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001886 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001887 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001888
Guido van Rossum43713e52000-02-29 13:59:29 +00001889 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001890 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001891 CHECK_TCL_APPARTMENT;
Guido van Rossum00d93061998-05-28 23:06:38 +00001892 ENTER_TCL
1893 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001894 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001895 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001896 res = Tkinter_Error(self);
1897 else
1898 res = Py_BuildValue("i", v);
1899 LEAVE_OVERLAP_TCL
1900 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001901}
1902
Barry Warsawfa701a81997-01-16 00:15:11 +00001903
1904
Guido van Rossum18468821994-06-20 07:49:28 +00001905static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001906Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001907{
Barry Warsawfa701a81997-01-16 00:15:11 +00001908 char *list;
1909 int argc;
1910 char **argv;
1911 PyObject *v;
1912 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001913
Martin v. Löwisffad6332002-11-26 09:28:05 +00001914 if (PyTuple_Size(args) == 1) {
1915 v = PyTuple_GetItem(args, 0);
1916 if (PyTuple_Check(v)) {
1917 Py_INCREF(v);
1918 return v;
1919 }
1920 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001921 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001922 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001923
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001924 if (Tcl_SplitList(Tkapp_Interp(self), list,
Neal Norwitzd1c55102003-05-29 00:17:03 +00001925 &argc, &argv) == TCL_ERROR) {
1926 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001927 return Tkinter_Error(self);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001928 }
Guido van Rossum18468821994-06-20 07:49:28 +00001929
Barry Warsawfa701a81997-01-16 00:15:11 +00001930 if (!(v = PyTuple_New(argc)))
Neal Norwitzd1c55102003-05-29 00:17:03 +00001931 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001932
Barry Warsawfa701a81997-01-16 00:15:11 +00001933 for (i = 0; i < argc; i++) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001934 PyObject *s = PyUnicode_FromString(argv[i]);
Barry Warsawfa701a81997-01-16 00:15:11 +00001935 if (!s || PyTuple_SetItem(v, i, s)) {
1936 Py_DECREF(v);
1937 v = NULL;
1938 goto finally;
1939 }
1940 }
Guido van Rossum18468821994-06-20 07:49:28 +00001941
Barry Warsawfa701a81997-01-16 00:15:11 +00001942 finally:
1943 ckfree(FREECAST argv);
Neal Norwitzd1c55102003-05-29 00:17:03 +00001944 PyMem_Free(list);
Barry Warsawfa701a81997-01-16 00:15:11 +00001945 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001946}
1947
1948static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001949Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001950{
Neal Norwitzd1c55102003-05-29 00:17:03 +00001951 PyObject *v;
Barry Warsawfa701a81997-01-16 00:15:11 +00001952 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001953
Martin v. Löwisffad6332002-11-26 09:28:05 +00001954 if (PyTuple_Size(args) == 1) {
1955 PyObject* o = PyTuple_GetItem(args, 0);
1956 if (PyTuple_Check(o)) {
1957 o = SplitObj(o);
1958 return o;
1959 }
1960 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001961 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001962 return NULL;
Neal Norwitzd1c55102003-05-29 00:17:03 +00001963 v = Split(list);
1964 PyMem_Free(list);
1965 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001966}
1967
1968static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001969Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001970{
Barry Warsawfa701a81997-01-16 00:15:11 +00001971 char *s = Merge(args);
1972 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001973
Barry Warsawfa701a81997-01-16 00:15:11 +00001974 if (s) {
Martin v. Löwis4040fb82007-08-13 06:01:43 +00001975 res = PyUnicode_FromString(s);
Barry Warsawfa701a81997-01-16 00:15:11 +00001976 ckfree(s);
1977 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001978
1979 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001980}
1981
Barry Warsawfa701a81997-01-16 00:15:11 +00001982
1983
Guido van Rossum18468821994-06-20 07:49:28 +00001984/** Tcl Command **/
1985
Guido van Rossum00d93061998-05-28 23:06:38 +00001986/* Client data struct */
1987typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001988 PyObject *self;
1989 PyObject *func;
1990} PythonCmd_ClientData;
1991
1992static int
Fred Drake509d79a2000-07-08 04:04:38 +00001993PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001994{
1995 errorInCmd = 1;
1996 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1997 LEAVE_PYTHON
1998 return TCL_ERROR;
1999}
2000
Guido van Rossum18468821994-06-20 07:49:28 +00002001/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00002002 * function or method.
2003 */
Guido van Rossum18468821994-06-20 07:49:28 +00002004static int
Fred Drake509d79a2000-07-08 04:04:38 +00002005PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00002006{
Guido van Rossum00d93061998-05-28 23:06:38 +00002007 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Hirokazu Yamamotode603472008-11-18 04:33:04 +00002008 PyObject *self, *func, *arg, *res;
Guido van Rossum2834b972000-10-06 16:58:26 +00002009 int i, rv;
Christian Heimes57dddfb2008-01-02 18:30:52 +00002010 Tcl_Obj *obj_res;
Guido van Rossum18468821994-06-20 07:49:28 +00002011
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002012 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002013
Barry Warsawfa701a81997-01-16 00:15:11 +00002014 /* TBD: no error checking here since we know, via the
2015 * Tkapp_CreateCommand() that the client data is a two-tuple
2016 */
Guido van Rossum00d93061998-05-28 23:06:38 +00002017 self = data->self;
2018 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00002019
Barry Warsawfa701a81997-01-16 00:15:11 +00002020 /* Create argument list (argv1, ..., argvN) */
2021 if (!(arg = PyTuple_New(argc - 1)))
2022 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00002023
Barry Warsawfa701a81997-01-16 00:15:11 +00002024 for (i = 0; i < (argc - 1); i++) {
Hirokazu Yamamotode603472008-11-18 04:33:04 +00002025 PyObject *s = PyUnicode_FromString(argv[i + 1]);
Barry Warsawfa701a81997-01-16 00:15:11 +00002026 if (!s || PyTuple_SetItem(arg, i, s)) {
2027 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00002028 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00002029 }
2030 }
2031 res = PyEval_CallObject(func, arg);
2032 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00002033
Barry Warsawfa701a81997-01-16 00:15:11 +00002034 if (res == NULL)
2035 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00002036
Christian Heimes57dddfb2008-01-02 18:30:52 +00002037 obj_res = AsObj(res);
2038 if (obj_res == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002039 Py_DECREF(res);
2040 return PythonCmd_Error(interp);
2041 }
Guido van Rossum2834b972000-10-06 16:58:26 +00002042 else {
Guilherme Polo56f5be52009-03-07 01:54:57 +00002043 Tcl_SetObjResult(interp, obj_res);
Guido van Rossum2834b972000-10-06 16:58:26 +00002044 rv = TCL_OK;
2045 }
2046
Barry Warsawfa701a81997-01-16 00:15:11 +00002047 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00002048
Guido van Rossum00d93061998-05-28 23:06:38 +00002049 LEAVE_PYTHON
2050
Guido van Rossum2834b972000-10-06 16:58:26 +00002051 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002052}
2053
2054static void
Fred Drake509d79a2000-07-08 04:04:38 +00002055PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002056{
Guido van Rossum00d93061998-05-28 23:06:38 +00002057 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2058
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002059 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002060 Py_XDECREF(data->self);
2061 Py_XDECREF(data->func);
2062 PyMem_DEL(data);
2063 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002064}
2065
Barry Warsawfa701a81997-01-16 00:15:11 +00002066
2067
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002068
Benjamin Peterson5879d412009-03-30 14:51:56 +00002069#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002070TCL_DECLARE_MUTEX(command_mutex)
2071
2072typedef struct CommandEvent{
2073 Tcl_Event ev;
2074 Tcl_Interp* interp;
2075 char *name;
2076 int create;
2077 int *status;
2078 ClientData *data;
Guilherme Polo491aee22009-02-06 23:16:11 +00002079 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002080} CommandEvent;
2081
2082static int
2083Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002084{
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002085 if (ev->create)
2086 *ev->status = Tcl_CreateCommand(
2087 ev->interp, ev->name, PythonCmd,
2088 ev->data, PythonCmdDelete) == NULL;
2089 else
2090 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2091 Tcl_MutexLock(&command_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00002092 Tcl_ConditionNotify(ev->done);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002093 Tcl_MutexUnlock(&command_mutex);
2094 return 1;
2095}
Benjamin Peterson5879d412009-03-30 14:51:56 +00002096#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002097
2098static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002099Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002100{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002101 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002102 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00002103 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00002104 PyObject *func;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002105 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002106
Guido van Rossum43713e52000-02-29 13:59:29 +00002107 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00002108 return NULL;
2109 if (!PyCallable_Check(func)) {
2110 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00002111 return NULL;
2112 }
Guido van Rossum18468821994-06-20 07:49:28 +00002113
Martin v. Löwisa9656492003-03-30 08:44:58 +00002114#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002115 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002116 !WaitForMainloop(self))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002117 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002118#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002119
Guido van Rossum00d93061998-05-28 23:06:38 +00002120 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00002121 if (!data)
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002122 return PyErr_NoMemory();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002123 Py_INCREF(self);
2124 Py_INCREF(func);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002125 data->self = selfptr;
Guido van Rossum00d93061998-05-28 23:06:38 +00002126 data->func = func;
Benjamin Peterson5879d412009-03-30 14:51:56 +00002127#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002128 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo491aee22009-02-06 23:16:11 +00002129 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002130 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2131 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2132 ev->interp = self->interp;
2133 ev->create = 1;
2134 ev->name = cmdName;
2135 ev->data = (ClientData)data;
2136 ev->status = &err;
Guilherme Polo491aee22009-02-06 23:16:11 +00002137 ev->done = &cond;
2138 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
2139 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002140 }
Benjamin Peterson5879d412009-03-30 14:51:56 +00002141 else
2142#endif
2143 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002144 ENTER_TCL
2145 err = Tcl_CreateCommand(
2146 Tkapp_Interp(self), cmdName, PythonCmd,
2147 (ClientData)data, PythonCmdDelete) == NULL;
2148 LEAVE_TCL
2149 }
2150 if (err) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002151 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00002152 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00002153 return NULL;
2154 }
Guido van Rossum18468821994-06-20 07:49:28 +00002155
Barry Warsawfa701a81997-01-16 00:15:11 +00002156 Py_INCREF(Py_None);
2157 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002158}
2159
Barry Warsawfa701a81997-01-16 00:15:11 +00002160
2161
Guido van Rossum18468821994-06-20 07:49:28 +00002162static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002163Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002164{
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002165 TkappObject *self = (TkappObject*)selfptr;
Barry Warsawfa701a81997-01-16 00:15:11 +00002166 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00002167 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002168
Guido van Rossum43713e52000-02-29 13:59:29 +00002169 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00002170 return NULL;
Benjamin Peterson5879d412009-03-30 14:51:56 +00002171
2172#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002173 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Guilherme Polo491aee22009-02-06 23:16:11 +00002174 Tcl_Condition cond = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002175 CommandEvent *ev;
2176 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2177 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2178 ev->interp = self->interp;
2179 ev->create = 0;
2180 ev->name = cmdName;
2181 ev->status = &err;
Guilherme Polo491aee22009-02-06 23:16:11 +00002182 ev->done = &cond;
2183 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002184 &command_mutex);
Guilherme Polo491aee22009-02-06 23:16:11 +00002185 Tcl_ConditionFinalize(&cond);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002186 }
Benjamin Peterson5879d412009-03-30 14:51:56 +00002187 else
2188#endif
2189 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002190 ENTER_TCL
2191 err = Tcl_DeleteCommand(self->interp, cmdName);
2192 LEAVE_TCL
2193 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002194 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002195 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2196 return NULL;
2197 }
2198 Py_INCREF(Py_None);
2199 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002200}
2201
Barry Warsawfa701a81997-01-16 00:15:11 +00002202
2203
Guido van Rossum00d93061998-05-28 23:06:38 +00002204#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002205/** File Handler **/
2206
Guido van Rossum00d93061998-05-28 23:06:38 +00002207typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00002208 PyObject *func;
2209 PyObject *file;
2210 int id;
2211 struct _fhcdata *next;
2212} FileHandler_ClientData;
2213
2214static FileHandler_ClientData *HeadFHCD;
2215
2216static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002217NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002218{
2219 FileHandler_ClientData *p;
2220 p = PyMem_NEW(FileHandler_ClientData, 1);
2221 if (p != NULL) {
2222 Py_XINCREF(func);
2223 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00002224 p->func = func;
2225 p->file = file;
2226 p->id = id;
2227 p->next = HeadFHCD;
2228 HeadFHCD = p;
2229 }
2230 return p;
2231}
2232
2233static void
Fred Drake509d79a2000-07-08 04:04:38 +00002234DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002235{
2236 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002237
2238 pp = &HeadFHCD;
Guido van Rossum00d93061998-05-28 23:06:38 +00002239 while ((p = *pp) != NULL) {
2240 if (p->id == id) {
2241 *pp = p->next;
2242 Py_XDECREF(p->func);
2243 Py_XDECREF(p->file);
2244 PyMem_DEL(p);
2245 }
2246 else
2247 pp = &p->next;
2248 }
2249}
2250
Guido van Rossuma597dde1995-01-10 20:56:29 +00002251static void
Fred Drake509d79a2000-07-08 04:04:38 +00002252FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002253{
Guido van Rossum00d93061998-05-28 23:06:38 +00002254 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00002255 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002256
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002257 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002258 func = data->func;
2259 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002260
Barry Warsawfa701a81997-01-16 00:15:11 +00002261 arg = Py_BuildValue("(Oi)", file, (long) mask);
2262 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00002263 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002264
2265 if (res == NULL) {
2266 errorInCmd = 1;
2267 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2268 }
2269 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002270 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002271}
2272
Guido van Rossum18468821994-06-20 07:49:28 +00002273static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002274Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2275 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002276{
Guido van Rossum00d93061998-05-28 23:06:38 +00002277 FileHandler_ClientData *data;
2278 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002279 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002280
Guido van Rossum2834b972000-10-06 16:58:26 +00002281 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2282 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002283 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002284
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002285 CHECK_TCL_APPARTMENT;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002286
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002287 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002288 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002289 return NULL;
2290 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002291 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002292 return NULL;
2293 }
2294
Guido van Rossuma80649b2000-03-28 20:07:05 +00002295 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002296 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002297 return NULL;
2298
Barry Warsawfa701a81997-01-16 00:15:11 +00002299 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002300 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002301 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00002302 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002303 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002304 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002305}
2306
2307static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002308Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002309{
Barry Warsawfa701a81997-01-16 00:15:11 +00002310 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00002311 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002312
Guido van Rossum43713e52000-02-29 13:59:29 +00002313 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00002314 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002315
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002316 CHECK_TCL_APPARTMENT;
Neal Norwitz12e22172003-03-03 21:16:39 +00002317
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00002318 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00002319 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002320 return NULL;
2321
Guido van Rossuma80649b2000-03-28 20:07:05 +00002322 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002323
Barry Warsawfa701a81997-01-16 00:15:11 +00002324 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00002325 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002326 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00002327 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002328 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00002329 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002330}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002331#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002332
Barry Warsawfa701a81997-01-16 00:15:11 +00002333
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002334/**** Tktt Object (timer token) ****/
2335
Jeremy Hylton938ace62002-07-17 16:30:39 +00002336static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002337
Guido van Rossum00d93061998-05-28 23:06:38 +00002338typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00002339 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00002340 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00002341 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002342} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002343
2344static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002345Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002346{
Barry Warsawfa701a81997-01-16 00:15:11 +00002347 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00002348 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002349
Guido van Rossum43713e52000-02-29 13:59:29 +00002350 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002351 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002352 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002353 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00002354 v->token = NULL;
2355 }
2356 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00002357 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002358 Py_DECREF(func);
2359 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00002360 }
2361 Py_INCREF(Py_None);
2362 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002363}
2364
2365static PyMethodDef Tktt_methods[] =
2366{
Neal Norwitzb0493252002-03-31 14:44:22 +00002367 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002368 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002369};
2370
2371static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002372Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002373{
Barry Warsawfa701a81997-01-16 00:15:11 +00002374 TkttObject *v;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002375
Guido van Rossumb18618d2000-05-03 23:44:39 +00002376 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00002377 if (v == NULL)
2378 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002379
Guido van Rossum00d93061998-05-28 23:06:38 +00002380 Py_INCREF(func);
2381 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002382 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002383
2384 /* Extra reference, deleted when called or when handler is deleted */
2385 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00002386 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002387}
2388
2389static void
Fred Drake509d79a2000-07-08 04:04:38 +00002390Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002391{
Guido van Rossum00d93061998-05-28 23:06:38 +00002392 TkttObject *v = (TkttObject *)self;
2393 PyObject *func = v->func;
2394
2395 Py_XDECREF(func);
2396
Guido van Rossumb18618d2000-05-03 23:44:39 +00002397 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002398}
2399
Guido van Rossum597ac201998-05-12 14:36:19 +00002400static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002401Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002402{
Barry Warsawfa701a81997-01-16 00:15:11 +00002403 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00002404 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002405
Tim Peters885d4572001-11-28 20:27:42 +00002406 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00002407 v->func == NULL ? ", handler deleted" : "");
Walter Dörwald1ab83302007-05-18 17:15:44 +00002408 return PyUnicode_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002409}
2410
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002411static PyTypeObject Tktt_Type =
2412{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002413 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002414 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002415 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002416 0, /*tp_itemsize */
2417 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00002418 0, /*tp_print */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002419 0, /*tp_getattr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002420 0, /*tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002421 0, /*tp_reserved */
Guido van Rossum597ac201998-05-12 14:36:19 +00002422 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002423 0, /*tp_as_number */
2424 0, /*tp_as_sequence */
2425 0, /*tp_as_mapping */
2426 0, /*tp_hash */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002427 0, /*tp_call*/
2428 0, /*tp_str*/
2429 0, /*tp_getattro*/
2430 0, /*tp_setattro*/
2431 0, /*tp_as_buffer*/
2432 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2433 0, /*tp_doc*/
2434 0, /*tp_traverse*/
2435 0, /*tp_clear*/
2436 0, /*tp_richcompare*/
2437 0, /*tp_weaklistoffset*/
2438 0, /*tp_iter*/
2439 0, /*tp_iternext*/
2440 Tktt_methods, /*tp_methods*/
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002441};
2442
Barry Warsawfa701a81997-01-16 00:15:11 +00002443
2444
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002445/** Timer Handler **/
2446
2447static void
Fred Drake509d79a2000-07-08 04:04:38 +00002448TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002449{
Guido van Rossum00d93061998-05-28 23:06:38 +00002450 TkttObject *v = (TkttObject *)clientData;
2451 PyObject *func = v->func;
2452 PyObject *res;
2453
2454 if (func == NULL)
2455 return;
2456
2457 v->func = NULL;
2458
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002459 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002460
2461 res = PyEval_CallObject(func, NULL);
2462 Py_DECREF(func);
2463 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002464
Barry Warsawfa701a81997-01-16 00:15:11 +00002465 if (res == NULL) {
2466 errorInCmd = 1;
2467 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2468 }
2469 else
2470 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002471
2472 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002473}
2474
2475static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002476Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002477{
Barry Warsawfa701a81997-01-16 00:15:11 +00002478 int milliseconds;
2479 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002480 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002481
Guido van Rossum2834b972000-10-06 16:58:26 +00002482 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2483 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00002484 return NULL;
2485 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00002486 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00002487 return NULL;
2488 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002489
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002490 CHECK_TCL_APPARTMENT;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002491
Guido van Rossum00d93061998-05-28 23:06:38 +00002492 v = Tktt_New(func);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002493 if (v) {
2494 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2495 (ClientData)v);
2496 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002497
Guido van Rossum00d93061998-05-28 23:06:38 +00002498 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002499}
2500
Barry Warsawfa701a81997-01-16 00:15:11 +00002501
Guido van Rossum18468821994-06-20 07:49:28 +00002502/** Event Loop **/
2503
Guido van Rossum18468821994-06-20 07:49:28 +00002504static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002505Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002506{
Barry Warsawfa701a81997-01-16 00:15:11 +00002507 int threshold = 0;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002508 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002509#ifdef WITH_THREAD
2510 PyThreadState *tstate = PyThreadState_Get();
2511#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002512
Guido van Rossum43713e52000-02-29 13:59:29 +00002513 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00002514 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002515
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002516 CHECK_TCL_APPARTMENT;
2517 self->dispatching = 1;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002518
Barry Warsawfa701a81997-01-16 00:15:11 +00002519 quitMainLoop = 0;
2520 while (Tk_GetNumMainWindows() > threshold &&
2521 !quitMainLoop &&
2522 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00002523 {
Guido van Rossum35d43371997-08-02 00:09:09 +00002524 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002525
2526#ifdef WITH_THREAD
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002527 if (self->threaded) {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002528 /* Allow other Python threads to run. */
2529 ENTER_TCL
2530 result = Tcl_DoOneEvent(0);
2531 LEAVE_TCL
2532 }
2533 else {
2534 Py_BEGIN_ALLOW_THREADS
2535 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2536 tcl_tstate = tstate;
2537 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2538 tcl_tstate = NULL;
2539 if(tcl_lock)PyThread_release_lock(tcl_lock);
2540 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002541 Sleep(Tkinter_busywaitinterval);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002542 Py_END_ALLOW_THREADS
2543 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002544#else
2545 result = Tcl_DoOneEvent(0);
2546#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002547
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002548 if (PyErr_CheckSignals() != 0) {
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002549 self->dispatching = 0;
Guido van Rossum35d43371997-08-02 00:09:09 +00002550 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002551 }
Guido van Rossum35d43371997-08-02 00:09:09 +00002552 if (result < 0)
2553 break;
Guido van Rossum18468821994-06-20 07:49:28 +00002554 }
Guilherme Polo3f5f8222009-01-03 22:00:39 +00002555 self->dispatching = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002556 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002557
Barry Warsawfa701a81997-01-16 00:15:11 +00002558 if (errorInCmd) {
2559 errorInCmd = 0;
2560 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2561 excInCmd = valInCmd = trbInCmd = NULL;
2562 return NULL;
2563 }
2564 Py_INCREF(Py_None);
2565 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002566}
2567
2568static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002569Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002570{
Guido van Rossum35d43371997-08-02 00:09:09 +00002571 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00002572 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002573
Guido van Rossum43713e52000-02-29 13:59:29 +00002574 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00002575 return NULL;
2576
Guido van Rossum00d93061998-05-28 23:06:38 +00002577 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002578 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00002579 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00002580 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002581}
2582
2583static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002584Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002585{
2586
Guido van Rossum43713e52000-02-29 13:59:29 +00002587 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00002588 return NULL;
2589
2590 quitMainLoop = 1;
2591 Py_INCREF(Py_None);
2592 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00002593}
2594
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002595static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002596Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002597{
2598
Guido van Rossum43713e52000-02-29 13:59:29 +00002599 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002600 return NULL;
2601
Christian Heimes217cfd12007-12-02 14:31:20 +00002602 return PyLong_FromLong((long)Tkapp_Interp(self));
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002603}
2604
David Aschere2b4b322004-02-18 05:59:53 +00002605static PyObject *
2606Tkapp_TkInit(PyObject *self, PyObject *args)
2607{
2608 Tcl_Interp *interp = Tkapp_Interp(self);
David Aschere2b4b322004-02-18 05:59:53 +00002609 const char * _tk_exists = NULL;
David Aschere2b4b322004-02-18 05:59:53 +00002610 int err;
David Aschere2b4b322004-02-18 05:59:53 +00002611
Guilherme Polob681df42009-02-09 22:33:59 +00002612#ifdef TKINTER_PROTECT_LOADTK
2613 /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the
2614 * first call failed.
2615 * To avoid the deadlock, we just refuse the second call through
2616 * a static variable.
2617 */
2618 if (tk_load_failed) {
2619 PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002620 return NULL;
2621 }
Guilherme Polob681df42009-02-09 22:33:59 +00002622#endif
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002623
David Aschere2b4b322004-02-18 05:59:53 +00002624 /* We want to guard against calling Tk_Init() multiple times */
2625 CHECK_TCL_APPARTMENT;
2626 ENTER_TCL
2627 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2628 ENTER_OVERLAP
2629 if (err == TCL_ERROR) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002630 /* This sets an exception, but we cannot return right
2631 away because we need to exit the overlap first. */
2632 Tkinter_Error(self);
David Aschere2b4b322004-02-18 05:59:53 +00002633 } else {
2634 _tk_exists = Tkapp_Result(self);
2635 }
2636 LEAVE_OVERLAP_TCL
2637 if (err == TCL_ERROR) {
2638 return NULL;
2639 }
2640 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2641 if (Tk_Init(interp) == TCL_ERROR) {
Guilherme Polob681df42009-02-09 22:33:59 +00002642 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
2643#ifdef TKINTER_PROTECT_LOADTK
2644 tk_load_failed = 1;
2645#endif
David Aschere2b4b322004-02-18 05:59:53 +00002646 return NULL;
2647 }
2648 }
2649 Py_INCREF(Py_None);
2650 return Py_None;
2651}
Barry Warsawfa701a81997-01-16 00:15:11 +00002652
Martin v. Löwisffad6332002-11-26 09:28:05 +00002653static PyObject *
2654Tkapp_WantObjects(PyObject *self, PyObject *args)
2655{
2656
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002657 int wantobjects = -1;
2658 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002659 return NULL;
Martin v. Löwisd6efae52003-06-14 21:34:32 +00002660 if (wantobjects == -1)
2661 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002662 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002663
2664 Py_INCREF(Py_None);
2665 return Py_None;
2666}
2667
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002668static PyObject *
2669Tkapp_WillDispatch(PyObject *self, PyObject *args)
2670{
2671
2672 ((TkappObject*)self)->dispatching = 1;
2673
2674 Py_INCREF(Py_None);
2675 return Py_None;
2676}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002677
Barry Warsawfa701a81997-01-16 00:15:11 +00002678
Guido van Rossum18468821994-06-20 07:49:28 +00002679/**** Tkapp Method List ****/
2680
2681static PyMethodDef Tkapp_methods[] =
2682{
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002683 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
Martin v. Löwisffad6332002-11-26 09:28:05 +00002684 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002685 {"call", Tkapp_Call, METH_VARARGS},
2686 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002687 {"eval", Tkapp_Eval, METH_VARARGS},
2688 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2689 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2690 {"record", Tkapp_Record, METH_VARARGS},
2691 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2692 {"setvar", Tkapp_SetVar, METH_VARARGS},
2693 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2694 {"getvar", Tkapp_GetVar, METH_VARARGS},
2695 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2696 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2697 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2698 {"getint", Tkapp_GetInt, METH_VARARGS},
2699 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2700 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2701 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2702 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2703 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2704 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2705 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2706 {"split", Tkapp_Split, METH_VARARGS},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002707 {"merge", Tkapp_Merge, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002708 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2709 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002710#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002711 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2712 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002713#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002714 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2715 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2716 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2717 {"quit", Tkapp_Quit, METH_VARARGS},
2718 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Neal Norwitz44dbae82004-02-19 02:44:22 +00002719 {"loadtk", Tkapp_TkInit, METH_NOARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002720 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002721};
2722
Barry Warsawfa701a81997-01-16 00:15:11 +00002723
2724
Guido van Rossum18468821994-06-20 07:49:28 +00002725/**** Tkapp Type Methods ****/
2726
2727static void
Fred Drake509d79a2000-07-08 04:04:38 +00002728Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002729{
Martin v. Löwisba2f8752002-12-31 17:34:30 +00002730 /*CHECK_TCL_APPARTMENT;*/
Guido van Rossum00d93061998-05-28 23:06:38 +00002731 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002732 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002733 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002734 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002735 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002736}
2737
Guido van Rossum18468821994-06-20 07:49:28 +00002738static PyTypeObject Tkapp_Type =
2739{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002740 PyVarObject_HEAD_INIT(NULL, 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00002741 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002742 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002743 0, /*tp_itemsize */
2744 Tkapp_Dealloc, /*tp_dealloc */
2745 0, /*tp_print */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002746 0, /*tp_getattr */
Barry Warsawfa701a81997-01-16 00:15:11 +00002747 0, /*tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002748 0, /*tp_reserved */
Barry Warsawfa701a81997-01-16 00:15:11 +00002749 0, /*tp_repr */
2750 0, /*tp_as_number */
2751 0, /*tp_as_sequence */
2752 0, /*tp_as_mapping */
2753 0, /*tp_hash */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00002754 0, /*tp_call*/
2755 0, /*tp_str*/
2756 0, /*tp_getattro*/
2757 0, /*tp_setattro*/
2758 0, /*tp_as_buffer*/
2759 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2760 0, /*tp_doc*/
2761 0, /*tp_traverse*/
2762 0, /*tp_clear*/
2763 0, /*tp_richcompare*/
2764 0, /*tp_weaklistoffset*/
2765 0, /*tp_iter*/
2766 0, /*tp_iternext*/
2767 Tkapp_methods, /*tp_methods*/
Guido van Rossum18468821994-06-20 07:49:28 +00002768};
2769
Barry Warsawfa701a81997-01-16 00:15:11 +00002770
2771
Guido van Rossum18468821994-06-20 07:49:28 +00002772/**** Tkinter Module ****/
2773
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002774typedef struct {
2775 PyObject* tuple;
2776 int size; /* current size */
2777 int maxsize; /* allocated size */
2778} FlattenContext;
2779
2780static int
2781_bump(FlattenContext* context, int size)
2782{
Guido van Rossum2834b972000-10-06 16:58:26 +00002783 /* expand tuple to hold (at least) size new items.
2784 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002785
2786 int maxsize = context->maxsize * 2;
2787
2788 if (maxsize < context->size + size)
2789 maxsize = context->size + size;
2790
2791 context->maxsize = maxsize;
2792
Tim Peters4324aa32001-05-28 22:30:08 +00002793 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002794}
2795
2796static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002797_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002798{
2799 /* add tuple or list to argument tuple (recursively) */
2800
2801 int i, size;
2802
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002803 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002804 PyErr_SetString(PyExc_ValueError,
2805 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002806 return 0;
2807 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002808 size = PyList_GET_SIZE(item);
2809 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002810 if (context->size + size > context->maxsize &&
2811 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002812 return 0;
2813 /* copy items to output tuple */
2814 for (i = 0; i < size; i++) {
2815 PyObject *o = PyList_GET_ITEM(item, i);
2816 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002817 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002818 return 0;
2819 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002820 if (context->size + 1 > context->maxsize &&
2821 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002822 return 0;
2823 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002824 PyTuple_SET_ITEM(context->tuple,
2825 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002826 }
2827 }
2828 } else if (PyTuple_Check(item)) {
2829 /* same, for tuples */
2830 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002831 if (context->size + size > context->maxsize &&
2832 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002833 return 0;
2834 for (i = 0; i < size; i++) {
2835 PyObject *o = PyTuple_GET_ITEM(item, i);
2836 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002837 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002838 return 0;
2839 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002840 if (context->size + 1 > context->maxsize &&
2841 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002842 return 0;
2843 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002844 PyTuple_SET_ITEM(context->tuple,
2845 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002846 }
2847 }
2848 } else {
2849 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2850 return 0;
2851 }
2852 return 1;
2853}
2854
2855static PyObject *
2856Tkinter_Flatten(PyObject* self, PyObject* args)
2857{
2858 FlattenContext context;
2859 PyObject* item;
2860
2861 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2862 return NULL;
2863
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002864 context.maxsize = PySequence_Size(item);
Benjamin Petersonc4bbc8d2009-01-30 03:39:35 +00002865 if (context.maxsize < 0)
2866 return NULL;
2867 if (context.maxsize == 0)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002868 return PyTuple_New(0);
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002869
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002870 context.tuple = PyTuple_New(context.maxsize);
2871 if (!context.tuple)
2872 return NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002873
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002874 context.size = 0;
2875
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002876 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002877 return NULL;
2878
Tim Peters4324aa32001-05-28 22:30:08 +00002879 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002880 return NULL;
2881
2882 return context.tuple;
2883}
2884
Guido van Rossum18468821994-06-20 07:49:28 +00002885static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002886Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002887{
Barry Warsawfa701a81997-01-16 00:15:11 +00002888 char *screenName = NULL;
Martin v. Löwisb9279bc2008-04-05 19:47:23 +00002889 char *baseName = NULL; /* XXX this is not used anymore;
2890 try getting rid of it. */
Barry Warsawfa701a81997-01-16 00:15:11 +00002891 char *className = NULL;
2892 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002893 int wantobjects = 0;
David Aschere2b4b322004-02-18 05:59:53 +00002894 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002895 int sync = 0; /* pass -sync to wish */
2896 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002897
Barry Warsawfa701a81997-01-16 00:15:11 +00002898 className = "Tk";
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002899
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002900 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002901 &screenName, &baseName, &className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002902 &interactive, &wantobjects, &wantTk,
2903 &sync, &use))
Barry Warsawfa701a81997-01-16 00:15:11 +00002904 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002905
Martin v. Löwisb9279bc2008-04-05 19:47:23 +00002906 return (PyObject *) Tkapp_New(screenName, className,
Martin v. Löwis1fa649f2004-08-03 18:45:31 +00002907 interactive, wantobjects, wantTk,
2908 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002909}
2910
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002911static PyObject *
2912Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2913{
2914 int new_val;
2915 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2916 return NULL;
2917 if (new_val < 0) {
2918 PyErr_SetString(PyExc_ValueError,
2919 "busywaitinterval must be >= 0");
2920 return NULL;
2921 }
2922 Tkinter_busywaitinterval = new_val;
2923 Py_INCREF(Py_None);
2924 return Py_None;
2925}
2926
2927static char setbusywaitinterval_doc[] =
2928"setbusywaitinterval(n) -> None\n\
2929\n\
2930Set the busy-wait interval in milliseconds between successive\n\
2931calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2932It should be set to a divisor of the maximum time between\n\
2933frames in an animation.";
2934
2935static PyObject *
2936Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2937{
Christian Heimes217cfd12007-12-02 14:31:20 +00002938 return PyLong_FromLong(Tkinter_busywaitinterval);
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002939}
2940
2941static char getbusywaitinterval_doc[] =
2942"getbusywaitinterval() -> int\n\
2943\n\
2944Return the current busy-wait interval between successive\n\
2945calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2946
Guido van Rossum18468821994-06-20 07:49:28 +00002947static PyMethodDef moduleMethods[] =
2948{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002949 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2950 {"create", Tkinter_Create, METH_VARARGS},
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002951 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2952 setbusywaitinterval_doc},
2953 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2954 METH_NOARGS, getbusywaitinterval_doc},
Barry Warsawfa701a81997-01-16 00:15:11 +00002955 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002956};
2957
Guido van Rossum7bf15641998-05-22 18:28:17 +00002958#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002959
2960static int stdin_ready = 0;
2961
Guido van Rossumad4db171998-06-13 13:56:28 +00002962#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002963static void
Fred Drake509d79a2000-07-08 04:04:38 +00002964MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002965{
2966 stdin_ready = 1;
2967}
Guido van Rossumad4db171998-06-13 13:56:28 +00002968#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002969
Martin v. Löwisa9656492003-03-30 08:44:58 +00002970#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002971static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002972#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002973
Guido van Rossum18468821994-06-20 07:49:28 +00002974static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002975EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002976{
Guido van Rossumad4db171998-06-13 13:56:28 +00002977#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002978 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002979#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002980#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002981 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002982#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002983 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002984 errorInCmd = 0;
2985#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002986 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002987 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002988#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002989 while (!errorInCmd && !stdin_ready) {
2990 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002991#ifdef MS_WINDOWS
2992 if (_kbhit()) {
2993 stdin_ready = 1;
2994 break;
2995 }
2996#endif
2997#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002998 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002999 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00003000 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003001
Guido van Rossum00d93061998-05-28 23:06:38 +00003002 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003003
3004 tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00003005 if(tcl_lock)PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00003006 if (result == 0)
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003007 Sleep(Tkinter_busywaitinterval);
Guido van Rossum00d93061998-05-28 23:06:38 +00003008 Py_END_ALLOW_THREADS
3009#else
3010 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003011#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003012
3013 if (result < 0)
3014 break;
3015 }
Guido van Rossumad4db171998-06-13 13:56:28 +00003016#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00003017 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00003018#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003019 if (errorInCmd) {
3020 errorInCmd = 0;
3021 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3022 excInCmd = valInCmd = trbInCmd = NULL;
3023 PyErr_Print();
3024 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003025#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00003026 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003027#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00003028 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00003029}
Guido van Rossum18468821994-06-20 07:49:28 +00003030
Guido van Rossum00d93061998-05-28 23:06:38 +00003031#endif
3032
Guido van Rossum7bf15641998-05-22 18:28:17 +00003033static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003034EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003035{
Guido van Rossum00d93061998-05-28 23:06:38 +00003036#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003037 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003038#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003039 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003040#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003041 PyOS_InputHook = EventHook;
3042 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003043#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003044}
3045
3046static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003047DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003048{
Guido van Rossum00d93061998-05-28 23:06:38 +00003049#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003050 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3051 PyOS_InputHook = NULL;
3052 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003053#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003054}
3055
Barry Warsawfa701a81997-01-16 00:15:11 +00003056
3057/* all errors will be checked in one fell swoop in init_tkinter() */
3058static void
Fred Drake509d79a2000-07-08 04:04:38 +00003059ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003060{
Christian Heimes217cfd12007-12-02 14:31:20 +00003061 PyObject *v = PyLong_FromLong(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003062 if (v) {
3063 PyDict_SetItemString(d, name, v);
3064 Py_DECREF(v);
3065 }
3066}
3067static void
Fred Drake509d79a2000-07-08 04:04:38 +00003068ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00003069{
Martin v. Löwis4040fb82007-08-13 06:01:43 +00003070 PyObject *v = PyUnicode_FromString(val);
Barry Warsawfa701a81997-01-16 00:15:11 +00003071 if (v) {
3072 PyDict_SetItemString(d, name, v);
3073 Py_DECREF(v);
3074 }
3075}
3076
3077
Martin v. Löwis1a214512008-06-11 05:26:20 +00003078static struct PyModuleDef _tkintermodule = {
3079 PyModuleDef_HEAD_INIT,
3080 "_tkinter",
3081 NULL,
3082 -1,
3083 moduleMethods,
3084 NULL,
3085 NULL,
3086 NULL,
3087 NULL
3088};
3089
Mark Hammond62b1ab12002-07-23 06:31:15 +00003090PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00003091PyInit__tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003092{
Martin v. Löwis790465f2008-04-05 20:41:37 +00003093 PyObject *m, *d, *uexe, *cexe;
Guido van Rossum18468821994-06-20 07:49:28 +00003094
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00003095 if (PyType_Ready(&Tkapp_Type) < 0)
3096 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00003097
3098#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00003099 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00003100#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003101
Martin v. Löwis1a214512008-06-11 05:26:20 +00003102 m = PyModule_Create(&_tkintermodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003103 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00003104 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00003105
Barry Warsawfa701a81997-01-16 00:15:11 +00003106 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00003107 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00003108 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00003109
Guido van Rossum35d43371997-08-02 00:09:09 +00003110 ins_long(d, "READABLE", TCL_READABLE);
3111 ins_long(d, "WRITABLE", TCL_WRITABLE);
3112 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3113 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3114 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3115 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3116 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3117 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3118 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00003119 ins_string(d, "TK_VERSION", TK_VERSION);
3120 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00003121
Guido van Rossum83551bf1997-09-13 00:44:23 +00003122 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00003123
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00003124 if (PyType_Ready(&Tktt_Type) < 0)
3125 return NULL;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003126 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3127
Christian Heimes90aa7642007-12-19 02:45:37 +00003128 Py_TYPE(&PyTclObject_Type) = &PyType_Type;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003129 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00003130
3131#ifdef TK_AQUA
3132 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3133 * start waking up. Note that Tcl_FindExecutable will do this, this
3134 * code must be above it! The original warning from
3135 * tkMacOSXAppInit.c is copied below.
3136 *
3137 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3138 * Tcl interpreter for now. It probably should work to do this
3139 * in the other order, but for now it doesn't seem to.
3140 *
3141 */
3142 Tk_MacOSXSetupTkNotifier();
3143#endif
3144
3145
Guido van Rossume187b0e2000-03-27 21:46:29 +00003146 /* This helps the dynamic loader; in Unicode aware Tcl versions
3147 it also helps Tcl find its encodings. */
Martin v. Löwis790465f2008-04-05 20:41:37 +00003148 uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1);
3149 if (uexe) {
3150 cexe = PyUnicode_AsEncodedString(uexe,
3151 Py_FileSystemDefaultEncoding,
3152 NULL);
3153 if (cexe)
Christian Heimes72b710a2008-05-26 13:28:38 +00003154 Tcl_FindExecutable(PyBytes_AsString(cexe));
Martin v. Löwis790465f2008-04-05 20:41:37 +00003155 Py_XDECREF(cexe);
3156 Py_DECREF(uexe);
3157 }
Guido van Rossume187b0e2000-03-27 21:46:29 +00003158
Martin v. Löwis1a214512008-06-11 05:26:20 +00003159 if (PyErr_Occurred()) {
3160 Py_DECREF(m);
3161 return NULL;
3162 }
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003163
Guido van Rossum43ff8681998-07-14 18:02:13 +00003164#if 0
3165 /* This was not a good idea; through <Destroy> bindings,
3166 Tcl_Finalize() may invoke Python code but at that point the
3167 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003168 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003169#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +00003170 return m;
Guido van Rossum18468821994-06-20 07:49:28 +00003171}