blob: 6d777d3f77d070769a66e4fc6278c58766bdb6df [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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +030036#define CHECK_SIZE(size, elemsize) \
37 ((size_t)(size) <= Py_MAX((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize)))
38
Martin v. Löwis71e25a02002-10-01 18:08:06 +000039/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
40 making _tkinter correct for this API means to break earlier
41 versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
42 earlier versions. Once Tcl releases before 8.4 don't need to be supported
43 anymore, this should go. */
44#define USE_COMPAT_CONST
45
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000046/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
47 it always; if Tcl is not threaded, the thread functions in
48 Tcl are empty. */
49#define TCL_THREADS
50
Jack Jansencb852442001-12-09 23:15:56 +000051#ifdef TK_FRAMEWORK
52#include <Tcl/tcl.h>
53#include <Tk/tk.h>
54#else
Guido van Rossum18468821994-06-20 07:49:28 +000055#include <tcl.h>
56#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000057#endif
Guido van Rossum18468821994-06-20 07:49:28 +000058
Guilherme Polo2d87e422009-04-10 22:19:09 +000059#include "tkinter.h"
60
Jason Tishlerbbe89612002-12-31 20:30:46 +000061/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
Martin v. Löwis5b177f12002-12-30 18:14:15 +000062#ifndef CONST84_RETURN
63#define CONST84_RETURN
Jason Tishlerbbe89612002-12-31 20:30:46 +000064#undef CONST
Martin v. Löwis5b177f12002-12-30 18:14:15 +000065#define CONST
66#endif
67
Guilherme Polo66917722009-02-09 22:35:27 +000068#if TK_VERSION_HEX < 0x08030102
69#error "Tk older than 8.3.1 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000070#endif
71
Jack Janseneddc1442003-11-20 01:44:59 +000072#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
Guido van Rossum0d2390c1997-08-14 19:57:07 +000073#define HAVE_CREATEFILEHANDLER
74#endif
75
Guido van Rossum00d93061998-05-28 23:06:38 +000076#ifdef HAVE_CREATEFILEHANDLER
77
Neal Norwitzd948a432006-01-08 01:08:55 +000078/* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere
79 with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */
80#ifndef TCL_UNIX_FD
81# ifdef TCL_WIN_SOCKET
82# define TCL_UNIX_FD (! TCL_WIN_SOCKET)
83# else
84# define TCL_UNIX_FD 1
85# endif
86#endif
87
Guido van Rossum00d93061998-05-28 23:06:38 +000088/* Tcl_CreateFileHandler() changed several times; these macros deal with the
89 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
90 Unix, only because Jack added it back); when available on Windows, it only
91 applies to sockets. */
92
Guido van Rossum7bf15641998-05-22 18:28:17 +000093#ifdef MS_WINDOWS
94#define FHANDLETYPE TCL_WIN_SOCKET
95#else
96#define FHANDLETYPE TCL_UNIX_FD
97#endif
98
Guido van Rossum00d93061998-05-28 23:06:38 +000099/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
100 which uses this to handle Tcl events while the user is typing commands. */
101
102#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000103#define WAIT_FOR_STDIN
104#endif
105
Guido van Rossum00d93061998-05-28 23:06:38 +0000106#endif /* HAVE_CREATEFILEHANDLER */
107
Guido van Rossumad4db171998-06-13 13:56:28 +0000108#ifdef MS_WINDOWS
109#include <conio.h>
110#define WAIT_FOR_STDIN
111#endif
112
Guido van Rossum00d93061998-05-28 23:06:38 +0000113#ifdef WITH_THREAD
114
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000115/* The threading situation is complicated. Tcl is not thread-safe, except
116 when configured with --enable-threads.
Guido van Rossum00d93061998-05-28 23:06:38 +0000117
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300118 So we need to use a lock around all uses of Tcl. Previously, the
119 Python interpreter lock was used for this. However, this causes
120 problems when other Python threads need to run while Tcl is blocked
121 waiting for events.
Guido van Rossum00d93061998-05-28 23:06:38 +0000122
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300123 To solve this problem, a separate lock for Tcl is introduced.
124 Holding it is incompatible with holding Python's interpreter lock.
125 The following four macros manipulate both locks together.
Guido van Rossum00d93061998-05-28 23:06:38 +0000126
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300127 ENTER_TCL and LEAVE_TCL are brackets, just like
128 Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS. They should be
129 used whenever a call into Tcl is made that could call an event
130 handler, or otherwise affect the state of a Tcl interpreter. These
131 assume that the surrounding code has the Python interpreter lock;
132 inside the brackets, the Python interpreter lock has been released
133 and the lock for Tcl has been acquired.
134
135 Sometimes, it is necessary to have both the Python lock and the Tcl
136 lock. (For example, when transferring data from the Tcl
137 interpreter result to a Python string object.) This can be done by
138 using different macros to close the ENTER_TCL block: ENTER_OVERLAP
139 reacquires the Python lock (and restores the thread state) but
140 doesn't release the Tcl lock; LEAVE_OVERLAP_TCL releases the Tcl
141 lock.
Guido van Rossum5e977831998-06-15 14:03:52 +0000142
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000143 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300144 handlers when the handler needs to use Python. Such event handlers
145 are entered while the lock for Tcl is held; the event handler
146 presumably needs to use Python. ENTER_PYTHON releases the lock for
147 Tcl and acquires the Python interpreter lock, restoring the
148 appropriate thread state, and LEAVE_PYTHON releases the Python
149 interpreter lock and re-acquires the lock for Tcl. It is okay for
150 ENTER_TCL/LEAVE_TCL pairs to be contained inside the code between
151 ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000152
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300153 These locks expand to several statements and brackets; they should
154 not be used in branches of if statements and the like.
Guido van Rossum00d93061998-05-28 23:06:38 +0000155
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300156 If Tcl is threaded, this approach won't work anymore. The Tcl
157 interpreter is only valid in the thread that created it, and all Tk
158 activity must happen in this thread, also. That means that the
159 mainloop must be invoked in the thread that created the
160 interpreter. Invoking commands from other threads is possible;
161 _tkinter will queue an event for the interpreter thread, which will
162 then execute the command and pass back the result. If the main
163 thread is not in the mainloop, and invoking commands causes an
164 exception; if the main loop is running but not processing events,
165 the command invocation will block.
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000166
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300167 In addition, for a threaded Tcl, a single global tcl_tstate won't
168 be sufficient anymore, since multiple Tcl interpreters may
169 simultaneously dispatch in different threads. So we use the Tcl TLS
170 API.
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000171
Guido van Rossum00d93061998-05-28 23:06:38 +0000172*/
173
Guido van Rossum65d5b571998-12-21 19:32:43 +0000174static PyThread_type_lock tcl_lock = 0;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000175
176#ifdef TCL_THREADS
177static Tcl_ThreadDataKey state_key;
178typedef PyThreadState *ThreadSpecificData;
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300179#define tcl_tstate \
180 (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*)))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000181#else
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000182static PyThreadState *tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000183#endif
Guido van Rossum00d93061998-05-28 23:06:38 +0000184
185#define ENTER_TCL \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
187 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000188
189#define LEAVE_TCL \
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300190 tcl_tstate = NULL; \
191 if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000192
Guido van Rossum62320c91998-06-15 04:36:09 +0000193#define ENTER_OVERLAP \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 Py_END_ALLOW_THREADS
Guido van Rossum62320c91998-06-15 04:36:09 +0000195
196#define LEAVE_OVERLAP_TCL \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000198
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000199#define ENTER_PYTHON \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300201 if(tcl_lock) \
202 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000203
204#define LEAVE_PYTHON \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 { PyThreadState *tstate = PyEval_SaveThread(); \
206 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000207
208#define CHECK_TCL_APPARTMENT \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 if (((TkappObject *)self)->threaded && \
210 ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300211 PyErr_SetString(PyExc_RuntimeError, \
212 "Calling Tcl from different appartment"); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 return 0; \
214 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000215
216#else
217
218#define ENTER_TCL
219#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000220#define ENTER_OVERLAP
221#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000222#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000223#define LEAVE_PYTHON
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000224#define CHECK_TCL_APPARTMENT
Guido van Rossum00d93061998-05-28 23:06:38 +0000225
226#endif
227
Guido van Rossum97867b21996-08-08 19:09:53 +0000228#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000229#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000230#endif
231
Guido van Rossum18468821994-06-20 07:49:28 +0000232/**** Tkapp Object Declaration ****/
233
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300234static PyObject *Tkapp_Type;
Guido van Rossum18468821994-06-20 07:49:28 +0000235
Guido van Rossum00d93061998-05-28 23:06:38 +0000236typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 PyObject_HEAD
238 Tcl_Interp *interp;
239 int wantobjects;
240 int threaded; /* True if tcl_platform[threaded] */
241 Tcl_ThreadId thread_id;
242 int dispatching;
243 /* We cannot include tclInt.h, as this is internal.
244 So we cache interesting types here. */
245 Tcl_ObjType *BooleanType;
246 Tcl_ObjType *ByteArrayType;
247 Tcl_ObjType *DoubleType;
248 Tcl_ObjType *IntType;
249 Tcl_ObjType *ListType;
250 Tcl_ObjType *ProcBodyType;
251 Tcl_ObjType *StringType;
Guido van Rossum00d93061998-05-28 23:06:38 +0000252} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000253
Guido van Rossum18468821994-06-20 07:49:28 +0000254#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000255#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000256
Guido van Rossum35d43371997-08-02 00:09:09 +0000257#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Christian Heimes90aa7642007-12-19 02:45:37 +0000258(void *) v, Py_REFCNT(v)))
Guido van Rossum18468821994-06-20 07:49:28 +0000259
Barry Warsawfa701a81997-01-16 00:15:11 +0000260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261
Guido van Rossum18468821994-06-20 07:49:28 +0000262/**** Error Handling ****/
263
264static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000265static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000266static int errorInCmd = 0;
267static PyObject *excInCmd;
268static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000270
Guilherme Polob681df42009-02-09 22:33:59 +0000271#ifdef TKINTER_PROTECT_LOADTK
Alexandre Vassalotti21455952009-04-05 01:30:02 +0000272static int tk_load_failed = 0;
Guilherme Polob681df42009-02-09 22:33:59 +0000273#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275
Guido van Rossum18468821994-06-20 07:49:28 +0000276static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000277Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000278{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
280 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000281}
282
Barry Warsawfa701a81997-01-16 00:15:11 +0000283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284
Guido van Rossum18468821994-06-20 07:49:28 +0000285/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000286
Martin v. Löwis28e9ce92003-05-09 08:19:48 +0000287static int Tkinter_busywaitinterval = 20;
288
Guido van Rossum00d93061998-05-28 23:06:38 +0000289#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000290#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000291
Guido van Rossum00d93061998-05-28 23:06:38 +0000292/* Millisecond sleep() for Unix platforms. */
293
294static void
Fred Drake509d79a2000-07-08 04:04:38 +0000295Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000296{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 /* XXX Too bad if you don't have select(). */
298 struct timeval t;
299 t.tv_sec = milli/1000;
300 t.tv_usec = (milli%1000) * 1000;
301 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
Guido van Rossum00d93061998-05-28 23:06:38 +0000302}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000303#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000304
Martin v. Löwis5b26abb2002-12-28 09:23:09 +0000305/* Wait up to 1s for the mainloop to come up. */
306
307static int
308WaitForMainloop(TkappObject* self)
309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 int i;
311 for (i = 0; i < 10; i++) {
312 if (self->dispatching)
313 return 1;
314 Py_BEGIN_ALLOW_THREADS
315 Sleep(100);
316 Py_END_ALLOW_THREADS
317 }
318 if (self->dispatching)
319 return 1;
320 PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
321 return 0;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +0000322}
Martin v. Löwisa9656492003-03-30 08:44:58 +0000323#endif /* WITH_THREAD */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326
Guido van Rossum18468821994-06-20 07:49:28 +0000327#define ARGSZ 64
328
Barry Warsawfa701a81997-01-16 00:15:11 +0000329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330
Guido van Rossum18468821994-06-20 07:49:28 +0000331static PyObject *
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200332unicodeFromTclStringAndSize(const char *s, Py_ssize_t size)
333{
334 PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL);
335 if (!r && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
336 /* Tcl encodes null character as \xc0\x80 */
337 if (memchr(s, '\xc0', size)) {
338 char *buf, *q;
339 const char *e = s + size;
340 PyErr_Clear();
341 q = buf = (char *)PyMem_Malloc(size);
Serhiy Storchakab1ebfdd2014-07-14 12:20:15 +0300342 if (buf == NULL) {
343 PyErr_NoMemory();
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200344 return NULL;
Serhiy Storchakab1ebfdd2014-07-14 12:20:15 +0300345 }
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200346 while (s != e) {
347 if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') {
348 *q++ = '\0';
349 s += 2;
350 }
351 else
352 *q++ = *s++;
353 }
354 s = buf;
355 size = q - s;
356 r = PyUnicode_DecodeUTF8(s, size, NULL);
357 PyMem_Free(buf);
358 }
359 }
360 return r;
361}
362
363static PyObject *
364unicodeFromTclString(const char *s)
365{
366 return unicodeFromTclStringAndSize(s, strlen(s));
367}
368
369static PyObject *
370unicodeFromTclObj(Tcl_Obj *value)
371{
372 int len;
373 char *s = Tcl_GetStringFromObj(value, &len);
374 return unicodeFromTclStringAndSize(s, len);
375}
376
377
378static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000379Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 int argc;
382 char **argv;
383 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 if (list == NULL) {
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +0300386 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 }
Guido van Rossum18468821994-06-20 07:49:28 +0000388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
390 /* Not a list.
391 * Could be a quoted string containing funnies, e.g. {"}.
392 * Return the string itself.
393 */
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200394 return unicodeFromTclString(list);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 }
Guido van Rossum18468821994-06-20 07:49:28 +0000396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 if (argc == 0)
398 v = PyUnicode_FromString("");
399 else if (argc == 1)
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200400 v = unicodeFromTclString(argv[0]);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 else if ((v = PyTuple_New(argc)) != NULL) {
402 int i;
403 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 for (i = 0; i < argc; i++) {
406 if ((w = Split(argv[i])) == NULL) {
407 Py_DECREF(v);
408 v = NULL;
409 break;
410 }
411 PyTuple_SetItem(v, i, w);
412 }
413 }
414 Tcl_Free(FREECAST argv);
415 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000416}
417
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300418/* In some cases, Tcl will still return strings that are supposed to
419 be lists. SplitObj walks through a nested tuple, finding string
420 objects that need to be split. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000421
Martin v. Löwis59683e82008-06-13 07:50:45 +0000422static PyObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000423SplitObj(PyObject *arg)
424{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 if (PyTuple_Check(arg)) {
426 int i, size;
427 PyObject *elem, *newelem, *result;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 size = PyTuple_Size(arg);
430 result = NULL;
431 /* Recursively invoke SplitObj for all tuple items.
432 If this does not return a new object, no action is
433 needed. */
434 for(i = 0; i < size; i++) {
435 elem = PyTuple_GetItem(arg, i);
436 newelem = SplitObj(elem);
437 if (!newelem) {
438 Py_XDECREF(result);
439 return NULL;
440 }
441 if (!result) {
442 int k;
443 if (newelem == elem) {
444 Py_DECREF(newelem);
445 continue;
446 }
447 result = PyTuple_New(size);
448 if (!result)
449 return NULL;
450 for(k = 0; k < i; k++) {
451 elem = PyTuple_GetItem(arg, k);
452 Py_INCREF(elem);
453 PyTuple_SetItem(result, k, elem);
454 }
455 }
456 PyTuple_SetItem(result, i, newelem);
457 }
458 if (result)
459 return result;
460 /* Fall through, returning arg. */
461 }
Serhiy Storchaka275d5fd2013-07-11 20:34:47 +0300462 else if (PyUnicode_Check(arg)) {
463 int argc;
464 char **argv;
465 char *list = PyUnicode_AsUTF8(arg);
466
467 if (list == NULL ||
468 Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
469 Py_INCREF(arg);
470 return arg;
471 }
472 Tcl_Free(FREECAST argv);
473 if (argc > 1)
474 return Split(list);
475 /* Fall through, returning arg. */
476 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 else if (PyBytes_Check(arg)) {
478 int argc;
479 char **argv;
480 char *list = PyBytes_AsString(arg);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
483 Py_INCREF(arg);
484 return arg;
485 }
486 Tcl_Free(FREECAST argv);
487 if (argc > 1)
488 return Split(PyBytes_AsString(arg));
489 /* Fall through, returning arg. */
490 }
491 Py_INCREF(arg);
492 return arg;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000493}
Barry Warsawfa701a81997-01-16 00:15:11 +0000494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495
Guido van Rossum18468821994-06-20 07:49:28 +0000496/**** Tkapp Object ****/
497
498#ifndef WITH_APPINIT
499int
Fred Drake509d79a2000-07-08 04:04:38 +0000500Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 if (Tcl_Init(interp) == TCL_ERROR) {
505 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
506 return TCL_ERROR;
507 }
Guilherme Polob681df42009-02-09 22:33:59 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 _tkinter_skip_tk_init = Tcl_GetVar(interp,
510 "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
511 if (_tkinter_skip_tk_init != NULL &&
512 strcmp(_tkinter_skip_tk_init, "1") == 0) {
513 return TCL_OK;
514 }
Guilherme Polob681df42009-02-09 22:33:59 +0000515
516#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 if (tk_load_failed) {
518 PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG);
519 return TCL_ERROR;
520 }
Guilherme Polob681df42009-02-09 22:33:59 +0000521#endif
522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 if (Tk_Init(interp) == TCL_ERROR) {
Guilherme Polob681df42009-02-09 22:33:59 +0000524#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 tk_load_failed = 1;
Guilherme Polob681df42009-02-09 22:33:59 +0000526#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
528 return TCL_ERROR;
529 }
Guilherme Polob681df42009-02-09 22:33:59 +0000530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000532}
533#endif /* !WITH_APPINIT */
534
Guido van Rossum18468821994-06-20 07:49:28 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536
Barry Warsawfa701a81997-01-16 00:15:11 +0000537
538/* Initialize the Tk application; see the `main' function in
539 * `tkMain.c'.
540 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000541
Thomas Wouters58d05102000-07-24 14:43:35 +0000542static void EnableEventHook(void); /* Forward */
543static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000544
Barry Warsawfa701a81997-01-16 00:15:11 +0000545static TkappObject *
Martin v. Löwisb9279bc2008-04-05 19:47:23 +0000546Tkapp_New(char *screenName, char *className,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 int interactive, int wantobjects, int wantTk, int sync, char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 TkappObject *v;
550 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000551
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300552 v = PyObject_New(TkappObject, (PyTypeObject *) Tkapp_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000553 if (v == NULL)
554 return NULL;
Antoine Pitrou584e8152013-08-11 00:22:30 +0200555 Py_INCREF(Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 v->interp = Tcl_CreateInterp();
558 v->wantobjects = wantobjects;
559 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
560 TCL_GLOBAL_ONLY) != NULL;
561 v->thread_id = Tcl_GetCurrentThread();
562 v->dispatching = 0;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000563
564#ifndef TCL_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 if (v->threaded) {
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300566 PyErr_SetString(PyExc_RuntimeError,
567 "Tcl is threaded but _tkinter is not");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 Py_DECREF(v);
569 return 0;
570 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000571#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000572#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 if (v->threaded && tcl_lock) {
574 /* If Tcl is threaded, we don't need the lock. */
575 PyThread_free_lock(tcl_lock);
576 tcl_lock = NULL;
577 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000578#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 v->BooleanType = Tcl_GetObjType("boolean");
581 v->ByteArrayType = Tcl_GetObjType("bytearray");
582 v->DoubleType = Tcl_GetObjType("double");
583 v->IntType = Tcl_GetObjType("int");
584 v->ListType = Tcl_GetObjType("list");
585 v->ProcBodyType = Tcl_GetObjType("procbody");
586 v->StringType = Tcl_GetObjType("string");
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 /* Delete the 'exit' command, which can screw things up */
589 Tcl_DeleteCommand(v->interp, "exit");
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 if (screenName != NULL)
592 Tcl_SetVar2(v->interp, "env", "DISPLAY",
593 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 if (interactive)
596 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
597 else
598 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 /* This is used to get the application class for Tk 4.1 and up */
Serhiy Storchaka07940882014-09-11 10:38:54 +0300601 argv0 = (char*)attemptckalloc(strlen(className) + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 if (!argv0) {
603 PyErr_NoMemory();
604 Py_DECREF(v);
605 return NULL;
606 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 strcpy(argv0, className);
Antoine Pitroued8ba142011-10-04 13:50:21 +0200609 if (Py_ISUPPER(Py_CHARMASK(argv0[0])))
610 argv0[0] = Py_TOLOWER(Py_CHARMASK(argv0[0]));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
612 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 if (! wantTk) {
615 Tcl_SetVar(v->interp,
616 "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
617 }
Guilherme Polob681df42009-02-09 22:33:59 +0000618#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 else if (tk_load_failed) {
620 Tcl_SetVar(v->interp,
621 "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY);
622 }
Guilherme Polob681df42009-02-09 22:33:59 +0000623#endif
David Aschere2b4b322004-02-18 05:59:53 +0000624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 /* some initial arguments need to be in argv */
626 if (sync || use) {
627 char *args;
628 int len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 if (sync)
631 len += sizeof "-sync";
632 if (use)
633 len += strlen(use) + sizeof "-use ";
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000634
Serhiy Storchaka07940882014-09-11 10:38:54 +0300635 args = (char*)attemptckalloc(len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 if (!args) {
637 PyErr_NoMemory();
638 Py_DECREF(v);
639 return NULL;
640 }
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 args[0] = '\0';
643 if (sync)
644 strcat(args, "-sync");
645 if (use) {
646 if (sync)
647 strcat(args, " ");
648 strcat(args, "-use ");
649 strcat(args, use);
650 }
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
653 ckfree(args);
654 }
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 if (Tcl_AppInit(v->interp) != TCL_OK) {
657 PyObject *result = Tkinter_Error((PyObject *)v);
Guilherme Polob681df42009-02-09 22:33:59 +0000658#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000659 if (wantTk) {
660 const char *_tkinter_tk_failed;
661 _tkinter_tk_failed = Tcl_GetVar(v->interp,
662 "_tkinter_tk_failed", TCL_GLOBAL_ONLY);
Guilherme Polob681df42009-02-09 22:33:59 +0000663
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 if ( _tkinter_tk_failed != NULL &&
665 strcmp(_tkinter_tk_failed, "1") == 0) {
666 tk_load_failed = 1;
667 }
668 }
Guilherme Polob681df42009-02-09 22:33:59 +0000669#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 Py_DECREF((PyObject *)v);
671 return (TkappObject *)result;
672 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 EnableEventHook();
Guido van Rossum7bf15641998-05-22 18:28:17 +0000675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000677}
678
Barry Warsawfa701a81997-01-16 00:15:11 +0000679
Benjamin Peterson5879d412009-03-30 14:51:56 +0000680#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000681static void
682Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 Tcl_Condition *cond, Tcl_Mutex *mutex)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000684{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 Py_BEGIN_ALLOW_THREADS;
686 Tcl_MutexLock(mutex);
687 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
688 Tcl_ThreadAlert(self->thread_id);
689 Tcl_ConditionWait(cond, mutex, NULL);
690 Tcl_MutexUnlock(mutex);
691 Py_END_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000692}
Benjamin Peterson5879d412009-03-30 14:51:56 +0000693#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695
Guido van Rossum18468821994-06-20 07:49:28 +0000696/** Tcl Eval **/
697
Martin v. Löwisffad6332002-11-26 09:28:05 +0000698typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 PyObject_HEAD
700 Tcl_Obj *value;
701 PyObject *string; /* This cannot cause cycles. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000702} PyTclObject;
703
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300704static PyObject *PyTclObject_Type;
705#define PyTclObject_Check(v) ((v)->ob_type == (PyTypeObject *) PyTclObject_Type)
Martin v. Löwisffad6332002-11-26 09:28:05 +0000706
707static PyObject *
708newPyTclObject(Tcl_Obj *arg)
709{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710 PyTclObject *self;
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300711 self = PyObject_New(PyTclObject, (PyTypeObject *) PyTclObject_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 if (self == NULL)
713 return NULL;
Antoine Pitrou584e8152013-08-11 00:22:30 +0200714 Py_INCREF(PyTclObject_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 Tcl_IncrRefCount(arg);
716 self->value = arg;
717 self->string = NULL;
718 return (PyObject*)self;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000719}
720
721static void
722PyTclObject_dealloc(PyTclObject *self)
723{
Antoine Pitrou584e8152013-08-11 00:22:30 +0200724 PyObject *tp = (PyObject *) Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 Tcl_DecrRefCount(self->value);
726 Py_XDECREF(self->string);
727 PyObject_Del(self);
Antoine Pitrou584e8152013-08-11 00:22:30 +0200728 Py_DECREF(tp);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000729}
730
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000731static char*
732PyTclObject_TclString(PyObject *self)
733{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 return Tcl_GetString(((PyTclObject*)self)->value);
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000735}
736
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000737/* Like _str, but create Unicode if necessary. */
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000738PyDoc_STRVAR(PyTclObject_string__doc__,
Christian Heimesb2b62622007-11-22 05:56:35 +0000739"the string representation of this object, either as str or bytes");
Martin v. Löwis39195712003-01-04 00:33:13 +0000740
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000741static PyObject *
742PyTclObject_string(PyTclObject *self, void *ignored)
743{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000744 if (!self->string) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200745 self->string = unicodeFromTclObj(self->value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 if (!self->string)
747 return NULL;
748 }
749 Py_INCREF(self->string);
750 return self->string;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000751}
752
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000753static PyObject *
Walter Dörwald6720d912007-07-12 12:12:25 +0000754PyTclObject_str(PyTclObject *self, void *ignored)
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000755{
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200756 if (self->string) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000757 Py_INCREF(self->string);
758 return self->string;
759 }
760 /* XXX Could chache result if it is non-ASCII. */
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200761 return unicodeFromTclObj(self->value);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000762}
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000763
Martin v. Löwisffad6332002-11-26 09:28:05 +0000764static PyObject *
765PyTclObject_repr(PyTclObject *self)
766{
Serhiy Storchaka463bd4b2013-09-23 22:49:02 +0300767 PyObject *repr, *str = PyTclObject_str(self, NULL);
768 if (str == NULL)
769 return NULL;
770 repr = PyUnicode_FromFormat("<%s object: %R>",
771 self->value->typePtr->name, str);
772 Py_DECREF(str);
773 return repr;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000774}
775
Mark Dickinson211c6252009-02-01 10:28:51 +0000776#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
777
778static PyObject *
779PyTclObject_richcompare(PyObject *self, PyObject *other, int op)
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000780{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 int result;
782 PyObject *v;
Mark Dickinson211c6252009-02-01 10:28:51 +0000783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000784 /* neither argument should be NULL, unless something's gone wrong */
785 if (self == NULL || other == NULL) {
786 PyErr_BadInternalCall();
787 return NULL;
788 }
Mark Dickinson211c6252009-02-01 10:28:51 +0000789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000790 /* both arguments should be instances of PyTclObject */
791 if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) {
792 v = Py_NotImplemented;
793 goto finished;
794 }
Mark Dickinson211c6252009-02-01 10:28:51 +0000795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 if (self == other)
797 /* fast path when self and other are identical */
798 result = 0;
799 else
800 result = strcmp(Tcl_GetString(((PyTclObject *)self)->value),
801 Tcl_GetString(((PyTclObject *)other)->value));
802 /* Convert return value to a Boolean */
803 switch (op) {
804 case Py_EQ:
805 v = TEST_COND(result == 0);
806 break;
807 case Py_NE:
808 v = TEST_COND(result != 0);
809 break;
810 case Py_LE:
811 v = TEST_COND(result <= 0);
812 break;
813 case Py_GE:
814 v = TEST_COND(result >= 0);
815 break;
816 case Py_LT:
817 v = TEST_COND(result < 0);
818 break;
819 case Py_GT:
820 v = TEST_COND(result > 0);
821 break;
822 default:
823 PyErr_BadArgument();
824 return NULL;
825 }
Mark Dickinson211c6252009-02-01 10:28:51 +0000826 finished:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 Py_INCREF(v);
828 return v;
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000829}
830
Martin v. Löwis39195712003-01-04 00:33:13 +0000831PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
832
Martin v. Löwisffad6332002-11-26 09:28:05 +0000833static PyObject*
834get_typename(PyTclObject* obj, void* ignored)
835{
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200836 return unicodeFromTclString(obj->value->typePtr->name);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000837}
838
Martin v. Löwis39195712003-01-04 00:33:13 +0000839
Martin v. Löwisffad6332002-11-26 09:28:05 +0000840static PyGetSetDef PyTclObject_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 {"typename", (getter)get_typename, NULL, get_typename__doc__},
842 {"string", (getter)PyTclObject_string, NULL,
843 PyTclObject_string__doc__},
844 {0},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000845};
846
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300847static PyType_Slot PyTclObject_Type_slots[] = {
848 {Py_tp_dealloc, (destructor)PyTclObject_dealloc},
849 {Py_tp_repr, (reprfunc)PyTclObject_repr},
850 {Py_tp_str, (reprfunc)PyTclObject_str},
Andrew Svetlovd2217a82012-10-30 22:49:16 +0200851 {Py_tp_getattro, PyObject_GenericGetAttr},
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300852 {Py_tp_richcompare, PyTclObject_richcompare},
853 {Py_tp_getset, PyTclObject_getsetlist},
854 {0, 0}
Martin v. Löwisffad6332002-11-26 09:28:05 +0000855};
856
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300857static PyType_Spec PyTclObject_Type_spec = {
858 "_tkinter.Tcl_Obj",
859 sizeof(PyTclObject),
860 0,
861 Py_TPFLAGS_DEFAULT,
862 PyTclObject_Type_slots,
863};
864
865
Serhiy Storchaka79851d72014-05-30 14:24:03 +0300866#if PY_SIZE_MAX > INT_MAX
867#define CHECK_STRING_LENGTH(s) do { \
868 if (s != NULL && strlen(s) >= INT_MAX) { \
869 PyErr_SetString(PyExc_OverflowError, "string is too long"); \
870 return NULL; \
871 } } while(0)
872#else
873#define CHECK_STRING_LENGTH(s)
874#endif
875
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000876static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000877AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000878{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 Tcl_Obj *result;
880 long longVal;
881 int overflow;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000883 if (PyBytes_Check(value))
Serhiy Storchaka74596a82014-07-30 18:33:13 +0300884 return Tcl_NewByteArrayObj((unsigned char *)PyBytes_AS_STRING(value),
885 PyBytes_GET_SIZE(value));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 else if (PyBool_Check(value))
887 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
888 else if (PyLong_CheckExact(value) &&
889 ((longVal = PyLong_AsLongAndOverflow(value, &overflow)),
890 !overflow)) {
891 /* If there is an overflow in the long conversion,
892 fall through to default object handling. */
893 return Tcl_NewLongObj(longVal);
894 }
895 else if (PyFloat_Check(value))
896 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
897 else if (PyTuple_Check(value)) {
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +0300898 Tcl_Obj **argv;
899 Py_ssize_t size, i;
900
901 size = PyTuple_Size(value);
Serhiy Storchakaabf68ce2014-09-11 10:57:13 +0300902 if (size == 0)
903 return Tcl_NewListObj(0, NULL);
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +0300904 if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) {
905 PyErr_SetString(PyExc_OverflowError, "tuple is too long");
906 return NULL;
907 }
Serhiy Storchaka07940882014-09-11 10:38:54 +0300908 argv = (Tcl_Obj **) attemptckalloc(((size_t)size) * sizeof(Tcl_Obj *));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 if(!argv)
910 return 0;
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +0300911 for (i = 0; i < size; i++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 argv[i] = AsObj(PyTuple_GetItem(value,i));
913 result = Tcl_NewListObj(PyTuple_Size(value), argv);
914 ckfree(FREECAST argv);
915 return result;
916 }
917 else if (PyUnicode_Check(value)) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200918 void *inbuf;
919 Py_ssize_t size;
920 int kind;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 Tcl_UniChar *outbuf = NULL;
922 Py_ssize_t i;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200923 size_t allocsize;
924
925 if (PyUnicode_READY(value) == -1)
926 return NULL;
927
928 inbuf = PyUnicode_DATA(value);
929 size = PyUnicode_GET_LENGTH(value);
Serhiy Storchakaabf68ce2014-09-11 10:57:13 +0300930 if (size == 0)
931 return Tcl_NewUnicodeObj((const void *)"", 0);
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +0300932 if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) {
933 PyErr_SetString(PyExc_OverflowError, "string is too long");
934 return NULL;
935 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200936 kind = PyUnicode_KIND(value);
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200937 if (kind == sizeof(Tcl_UniChar))
938 return Tcl_NewUnicodeObj(inbuf, size);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200939 allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
Serhiy Storchaka07940882014-09-11 10:38:54 +0300940 outbuf = (Tcl_UniChar*)attemptckalloc(allocsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 /* Else overflow occurred, and we take the next exit */
942 if (!outbuf) {
943 PyErr_NoMemory();
944 return NULL;
945 }
946 for (i = 0; i < size; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200947 Py_UCS4 ch = PyUnicode_READ(kind, inbuf, i);
948 /* We cannot test for sizeof(Tcl_UniChar) directly,
949 so we test for UTF-8 size instead. */
950#if TCL_UTF_MAX == 3
951 if (ch >= 0x10000) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 /* Tcl doesn't do UTF-16, yet. */
Serhiy Storchaka59f5dee2013-02-18 13:01:52 +0200953 PyErr_Format(Tkinter_TclError,
Victor Stinner7ab41922011-11-04 00:36:46 +0100954 "character U+%x is above the range "
955 "(U+0000-U+FFFF) allowed by Tcl",
Victor Stinner3d7acb02011-11-04 09:49:24 +0100956 ch);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 ckfree(FREECAST outbuf);
958 return NULL;
959 }
Andrew Svetlov80823d72012-07-22 13:56:54 +0300960#endif
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200961 outbuf[i] = ch;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 }
963 result = Tcl_NewUnicodeObj(outbuf, size);
964 ckfree(FREECAST outbuf);
965 return result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 }
967 else if(PyTclObject_Check(value)) {
968 Tcl_Obj *v = ((PyTclObject*)value)->value;
969 Tcl_IncrRefCount(v);
970 return v;
971 }
972 else {
973 PyObject *v = PyObject_Str(value);
974 if (!v)
975 return 0;
976 result = AsObj(v);
977 Py_DECREF(v);
978 return result;
979 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000980}
981
Martin v. Löwisffad6332002-11-26 09:28:05 +0000982static PyObject*
983FromObj(PyObject* tkapp, Tcl_Obj *value)
984{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 PyObject *result = NULL;
986 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 if (value->typePtr == NULL) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200989 return unicodeFromTclStringAndSize(value->bytes, value->length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 if (value->typePtr == app->BooleanType) {
993 result = value->internalRep.longValue ? Py_True : Py_False;
994 Py_INCREF(result);
995 return result;
996 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 if (value->typePtr == app->ByteArrayType) {
999 int size;
1000 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
1001 return PyBytes_FromStringAndSize(data, size);
1002 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 if (value->typePtr == app->DoubleType) {
1005 return PyFloat_FromDouble(value->internalRep.doubleValue);
1006 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 if (value->typePtr == app->IntType) {
1009 return PyLong_FromLong(value->internalRep.longValue);
1010 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 if (value->typePtr == app->ListType) {
1013 int size;
1014 int i, status;
1015 PyObject *elem;
1016 Tcl_Obj *tcl_elem;
Martin v. Löwisffad6332002-11-26 09:28:05 +00001017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
1019 if (status == TCL_ERROR)
1020 return Tkinter_Error(tkapp);
1021 result = PyTuple_New(size);
1022 if (!result)
1023 return NULL;
1024 for (i = 0; i < size; i++) {
1025 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
1026 value, i, &tcl_elem);
1027 if (status == TCL_ERROR) {
1028 Py_DECREF(result);
1029 return Tkinter_Error(tkapp);
1030 }
1031 elem = FromObj(tkapp, tcl_elem);
1032 if (!elem) {
1033 Py_DECREF(result);
1034 return NULL;
1035 }
1036 PyTuple_SetItem(result, i, elem);
1037 }
1038 return result;
1039 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 if (value->typePtr == app->ProcBodyType) {
1042 /* fall through: return tcl object. */
1043 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 if (value->typePtr == app->StringType) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001046 return PyUnicode_FromKindAndData(
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001047 sizeof(Tcl_UniChar), Tcl_GetUnicode(value),
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001048 Tcl_GetCharLength(value));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 return newPyTclObject(value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001052}
1053
Benjamin Peterson5879d412009-03-30 14:51:56 +00001054#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001055/* This mutex synchronizes inter-thread command calls. */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001056TCL_DECLARE_MUTEX(call_mutex)
1057
1058typedef struct Tkapp_CallEvent {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 Tcl_Event ev; /* Must be first */
1060 TkappObject *self;
1061 PyObject *args;
1062 int flags;
1063 PyObject **res;
1064 PyObject **exc_type, **exc_value, **exc_tb;
1065 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001066} Tkapp_CallEvent;
Benjamin Peterson5879d412009-03-30 14:51:56 +00001067#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001068
1069void
1070Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 int i;
1073 for (i = 0; i < objc; i++)
1074 Tcl_DecrRefCount(objv[i]);
1075 if (objv != objStore)
1076 ckfree(FREECAST objv);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001077}
Guido van Rossum18468821994-06-20 07:49:28 +00001078
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001079/* Convert Python objects to Tcl objects. This must happen in the
1080 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001081
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001082static Tcl_Obj**
1083Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 Tcl_Obj **objv = objStore;
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +03001086 Py_ssize_t objc = 0, i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 if (args == NULL)
1088 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 else if (!PyTuple_Check(args)) {
1091 objv[0] = AsObj(args);
1092 if (objv[0] == 0)
1093 goto finally;
1094 objc = 1;
1095 Tcl_IncrRefCount(objv[0]);
1096 }
1097 else {
1098 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 if (objc > ARGSZ) {
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +03001101 if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) {
1102 PyErr_SetString(PyExc_OverflowError, "tuple is too long");
1103 return NULL;
1104 }
Serhiy Storchaka07940882014-09-11 10:38:54 +03001105 objv = (Tcl_Obj **)attemptckalloc(((size_t)objc) * sizeof(Tcl_Obj *));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 if (objv == NULL) {
1107 PyErr_NoMemory();
1108 objc = 0;
1109 goto finally;
1110 }
1111 }
Guido van Rossum212643f1998-04-29 16:22:14 +00001112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 for (i = 0; i < objc; i++) {
1114 PyObject *v = PyTuple_GetItem(args, i);
1115 if (v == Py_None) {
1116 objc = i;
1117 break;
1118 }
1119 objv[i] = AsObj(v);
1120 if (!objv[i]) {
1121 /* Reset objc, so it attempts to clear
1122 objects only up to i. */
1123 objc = i;
1124 goto finally;
1125 }
1126 Tcl_IncrRefCount(objv[i]);
1127 }
1128 }
1129 *pobjc = objc;
1130 return objv;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001131finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 Tkapp_CallDeallocArgs(objv, objStore, objc);
1133 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001134}
Guido van Rossum212643f1998-04-29 16:22:14 +00001135
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001136/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001137
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001138static PyObject*
1139Tkapp_CallResult(TkappObject *self)
1140{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 PyObject *res = NULL;
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001142 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 if(self->wantobjects) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 /* Not sure whether the IncrRef is necessary, but something
1145 may overwrite the interpreter result while we are
1146 converting it. */
1147 Tcl_IncrRefCount(value);
1148 res = FromObj((PyObject*)self, value);
1149 Tcl_DecrRefCount(value);
1150 } else {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001151 res = unicodeFromTclObj(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 }
1153 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001154}
Guido van Rossum632de272000-03-29 00:19:50 +00001155
Benjamin Peterson5879d412009-03-30 14:51:56 +00001156#ifdef WITH_THREAD
1157
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001158/* Tkapp_CallProc is the event procedure that is executed in the context of
1159 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1160 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001161
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001162static int
1163Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 Tcl_Obj *objStore[ARGSZ];
1166 Tcl_Obj **objv;
1167 int objc;
1168 int i;
1169 ENTER_PYTHON
1170 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1171 if (!objv) {
1172 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1173 *(e->res) = NULL;
1174 }
1175 LEAVE_PYTHON
1176 if (!objv)
1177 goto done;
1178 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1179 ENTER_PYTHON
1180 if (i == TCL_ERROR) {
1181 *(e->res) = NULL;
1182 *(e->exc_type) = NULL;
1183 *(e->exc_tb) = NULL;
1184 *(e->exc_value) = PyObject_CallFunction(
1185 Tkinter_TclError, "s",
1186 Tcl_GetStringResult(e->self->interp));
1187 }
1188 else {
1189 *(e->res) = Tkapp_CallResult(e->self);
1190 }
1191 LEAVE_PYTHON
Guilherme Polo491aee22009-02-06 23:16:11 +00001192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 Tkapp_CallDeallocArgs(objv, objStore, objc);
Guilherme Polo491aee22009-02-06 23:16:11 +00001194done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 /* Wake up calling thread. */
1196 Tcl_MutexLock(&call_mutex);
1197 Tcl_ConditionNotify(e->done);
1198 Tcl_MutexUnlock(&call_mutex);
1199 return 1;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001200}
1201
Benjamin Peterson5879d412009-03-30 14:51:56 +00001202#endif
1203
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001204/* This is the main entry point for calling a Tcl command.
1205 It supports three cases, with regard to threading:
1206 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1207 the context of the calling thread.
1208 2. Tcl is threaded, caller of the command is in the interpreter thread:
1209 Execute the command in the calling thread. Since the Tcl lock will
1210 not be used, we can merge that with case 1.
1211 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1212 the interpreter thread. Allocation of Tcl objects needs to occur in the
1213 interpreter thread, so we ship the PyObject* args to the target thread,
1214 and perform processing there. */
1215
1216static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001217Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001218{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 Tcl_Obj *objStore[ARGSZ];
1220 Tcl_Obj **objv = NULL;
1221 int objc, i;
1222 PyObject *res = NULL;
1223 TkappObject *self = (TkappObject*)selfptr;
1224 int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 /* If args is a single tuple, replace with contents of tuple */
1227 if (1 == PyTuple_Size(args)){
1228 PyObject* item = PyTuple_GetItem(args, 0);
1229 if (PyTuple_Check(item))
1230 args = item;
1231 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001232#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1234 /* We cannot call the command directly. Instead, we must
1235 marshal the parameters to the interpreter thread. */
1236 Tkapp_CallEvent *ev;
1237 Tcl_Condition cond = NULL;
1238 PyObject *exc_type, *exc_value, *exc_tb;
1239 if (!WaitForMainloop(self))
1240 return NULL;
Serhiy Storchaka07940882014-09-11 10:38:54 +03001241 ev = (Tkapp_CallEvent*)attemptckalloc(sizeof(Tkapp_CallEvent));
1242 if (ev == NULL) {
1243 PyErr_NoMemory();
1244 return NULL;
1245 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1247 ev->self = self;
1248 ev->args = args;
1249 ev->res = &res;
1250 ev->exc_type = &exc_type;
1251 ev->exc_value = &exc_value;
1252 ev->exc_tb = &exc_tb;
1253 ev->done = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 if (res == NULL) {
1258 if (exc_type)
1259 PyErr_Restore(exc_type, exc_value, exc_tb);
1260 else
1261 PyErr_SetObject(Tkinter_TclError, exc_value);
1262 }
1263 Tcl_ConditionFinalize(&cond);
1264 }
1265 else
Martin v. Löwisa9656492003-03-30 08:44:58 +00001266#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 objv = Tkapp_CallArgs(args, objStore, &objc);
1270 if (!objv)
1271 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 ENTER_TCL
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 ENTER_OVERLAP
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 if (i == TCL_ERROR)
1280 Tkinter_Error(selfptr);
1281 else
1282 res = Tkapp_CallResult(self);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 LEAVE_OVERLAP_TCL
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 Tkapp_CallDeallocArgs(objv, objStore, objc);
1287 }
1288 return res;
Barry Warsawfa701a81997-01-16 00:15:11 +00001289}
1290
1291
1292static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001293Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001294{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 char *script;
1296 PyObject *res = NULL;
1297 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 if (!PyArg_ParseTuple(args, "s:eval", &script))
1300 return NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001301
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001302 CHECK_STRING_LENGTH(script);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 ENTER_TCL
1306 err = Tcl_Eval(Tkapp_Interp(self), script);
1307 ENTER_OVERLAP
1308 if (err == TCL_ERROR)
1309 res = Tkinter_Error(self);
1310 else
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001311 res = unicodeFromTclString(Tkapp_Result(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 LEAVE_OVERLAP_TCL
1313 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001314}
1315
1316static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001317Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 char *fileName;
1320 PyObject *res = NULL;
1321 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
1324 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001325
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001326 CHECK_STRING_LENGTH(fileName);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 ENTER_TCL
1330 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
1331 ENTER_OVERLAP
1332 if (err == TCL_ERROR)
1333 res = Tkinter_Error(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 else
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001335 res = unicodeFromTclString(Tkapp_Result(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 LEAVE_OVERLAP_TCL
1337 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001338}
1339
1340static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001341Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 char *script;
1344 PyObject *res = NULL;
1345 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001346
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001347 if (!PyArg_ParseTuple(args, "s:record", &script))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001349
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001350 CHECK_STRING_LENGTH(script);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 ENTER_TCL
1354 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
1355 ENTER_OVERLAP
1356 if (err == TCL_ERROR)
1357 res = Tkinter_Error(self);
1358 else
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001359 res = unicodeFromTclString(Tkapp_Result(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 LEAVE_OVERLAP_TCL
1361 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001362}
1363
1364static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001365Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001366{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
1370 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001371 CHECK_STRING_LENGTH(msg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 ENTER_TCL
1375 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
1376 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001377
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03001378 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00001379}
1380
Barry Warsawfa701a81997-01-16 00:15:11 +00001381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382
Guido van Rossum18468821994-06-20 07:49:28 +00001383/** Tcl Variable **/
1384
Benjamin Peterson5879d412009-03-30 14:51:56 +00001385typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
1386
1387#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001388TCL_DECLARE_MUTEX(var_mutex)
1389
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001390typedef struct VarEvent {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 Tcl_Event ev; /* must be first */
1392 PyObject *self;
1393 PyObject *args;
1394 int flags;
1395 EventFunc func;
1396 PyObject **res;
1397 PyObject **exc_type;
1398 PyObject **exc_val;
1399 Tcl_Condition *cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001400} VarEvent;
Benjamin Peterson5879d412009-03-30 14:51:56 +00001401#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001402
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001403static int
1404varname_converter(PyObject *in, void *_out)
1405{
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001406 char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 char **out = (char**)_out;
1408 if (PyBytes_Check(in)) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001409 if (PyBytes_Size(in) > INT_MAX) {
1410 PyErr_SetString(PyExc_OverflowError, "bytes object is too long");
1411 return 0;
1412 }
1413 s = PyBytes_AsString(in);
1414 if (strlen(s) != PyBytes_Size(in)) {
1415 PyErr_SetString(PyExc_ValueError, "null byte in bytes object");
1416 return 0;
1417 }
1418 *out = s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 return 1;
1420 }
1421 if (PyUnicode_Check(in)) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001422 Py_ssize_t size;
1423 s = PyUnicode_AsUTF8AndSize(in, &size);
Christian Heimesd33491e2014-02-05 00:29:17 +01001424 if (s == NULL) {
1425 return 0;
1426 }
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001427 if (size > INT_MAX) {
1428 PyErr_SetString(PyExc_OverflowError, "string is too long");
1429 return 0;
1430 }
1431 if (strlen(s) != size) {
1432 PyErr_SetString(PyExc_ValueError, "null character in string");
1433 return 0;
1434 }
1435 *out = s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 return 1;
1437 }
1438 if (PyTclObject_Check(in)) {
1439 *out = PyTclObject_TclString(in);
1440 return 1;
1441 }
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001442 PyErr_Format(PyExc_TypeError,
1443 "must be str, bytes or Tcl_Obj, not %.50s",
1444 in->ob_type->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 return 0;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001446}
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001447
Benjamin Peterson5879d412009-03-30 14:51:56 +00001448#ifdef WITH_THREAD
1449
Martin v. Löwis59683e82008-06-13 07:50:45 +00001450static void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001451var_perform(VarEvent *ev)
1452{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1454 if (!*(ev->res)) {
1455 PyObject *exc, *val, *tb;
1456 PyErr_Fetch(&exc, &val, &tb);
1457 PyErr_NormalizeException(&exc, &val, &tb);
1458 *(ev->exc_type) = exc;
1459 *(ev->exc_val) = val;
1460 Py_DECREF(tb);
1461 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001462
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001463}
1464
1465static int
1466var_proc(VarEvent* ev, int flags)
1467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 ENTER_PYTHON
1469 var_perform(ev);
1470 Tcl_MutexLock(&var_mutex);
1471 Tcl_ConditionNotify(ev->cond);
1472 Tcl_MutexUnlock(&var_mutex);
1473 LEAVE_PYTHON
1474 return 1;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001475}
1476
Benjamin Peterson5879d412009-03-30 14:51:56 +00001477#endif
1478
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001479static PyObject*
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001480var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001481{
Martin v. Löwisa9656492003-03-30 08:44:58 +00001482#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 TkappObject *self = (TkappObject*)selfptr;
1484 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1485 TkappObject *self = (TkappObject*)selfptr;
1486 VarEvent *ev;
1487 PyObject *res, *exc_type, *exc_val;
1488 Tcl_Condition cond = NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 /* The current thread is not the interpreter thread. Marshal
1491 the call to the interpreter thread, then wait for
1492 completion. */
1493 if (!WaitForMainloop(self))
1494 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001495
Serhiy Storchaka07940882014-09-11 10:38:54 +03001496 ev = (VarEvent*)attemptckalloc(sizeof(VarEvent));
1497 if (ev == NULL) {
1498 PyErr_NoMemory();
1499 return NULL;
1500 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 ev->self = selfptr;
1502 ev->args = args;
1503 ev->flags = flags;
1504 ev->func = func;
1505 ev->res = &res;
1506 ev->exc_type = &exc_type;
1507 ev->exc_val = &exc_val;
1508 ev->cond = &cond;
1509 ev->ev.proc = (Tcl_EventProc*)var_proc;
1510 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
1511 Tcl_ConditionFinalize(&cond);
1512 if (!res) {
1513 PyErr_SetObject(exc_type, exc_val);
1514 Py_DECREF(exc_type);
1515 Py_DECREF(exc_val);
1516 return NULL;
1517 }
1518 return res;
1519 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001520#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 /* Tcl is not threaded, or this is the interpreter thread. */
1522 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001523}
1524
Guido van Rossum18468821994-06-20 07:49:28 +00001525static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001526SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 char *name1, *name2;
1529 PyObject *newValue;
1530 PyObject *res = NULL;
1531 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001532
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001533 switch (PyTuple_GET_SIZE(args)) {
1534 case 2:
1535 if (!PyArg_ParseTuple(args, "O&O:setvar",
1536 varname_converter, &name1, &newValue))
1537 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 /* XXX Acquire tcl lock??? */
1539 newval = AsObj(newValue);
1540 if (newval == NULL)
1541 return NULL;
1542 ENTER_TCL
1543 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1544 newval, flags);
1545 ENTER_OVERLAP
1546 if (!ok)
1547 Tkinter_Error(self);
1548 else {
1549 res = Py_None;
1550 Py_INCREF(res);
1551 }
1552 LEAVE_OVERLAP_TCL
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001553 break;
1554 case 3:
1555 if (!PyArg_ParseTuple(args, "ssO:setvar",
1556 &name1, &name2, &newValue))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001558 CHECK_STRING_LENGTH(name1);
1559 CHECK_STRING_LENGTH(name2);
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001560 /* XXX must hold tcl lock already??? */
1561 newval = AsObj(newValue);
1562 ENTER_TCL
1563 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1564 ENTER_OVERLAP
1565 if (!ok)
1566 Tkinter_Error(self);
1567 else {
1568 res = Py_None;
1569 Py_INCREF(res);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 }
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001571 LEAVE_OVERLAP_TCL
1572 break;
1573 default:
1574 PyErr_SetString(PyExc_TypeError, "setvar requires 2 to 3 arguments");
1575 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 }
1577 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001578}
1579
1580static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001581Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001582{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001584}
1585
1586static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001587Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001588{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001590}
1591
Barry Warsawfa701a81997-01-16 00:15:11 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593
Guido van Rossum18468821994-06-20 07:49:28 +00001594static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001595GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001596{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 char *name1, *name2=NULL;
1598 PyObject *res = NULL;
1599 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 if (!PyArg_ParseTuple(args, "O&|s:getvar",
1602 varname_converter, &name1, &name2))
1603 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001604
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001605 CHECK_STRING_LENGTH(name2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 ENTER_TCL
1607 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1608 ENTER_OVERLAP
1609 if (tres == NULL) {
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +03001610 PyErr_SetString(Tkinter_TclError,
1611 Tcl_GetStringResult(Tkapp_Interp(self)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 } else {
1613 if (((TkappObject*)self)->wantobjects) {
1614 res = FromObj(self, tres);
1615 }
1616 else {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001617 res = unicodeFromTclObj(tres);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 }
1619 }
1620 LEAVE_OVERLAP_TCL
1621 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001622}
1623
1624static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001625Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001628}
1629
1630static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001631Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001634}
1635
Barry Warsawfa701a81997-01-16 00:15:11 +00001636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637
Guido van Rossum18468821994-06-20 07:49:28 +00001638static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001639UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 char *name1, *name2=NULL;
1642 int code;
1643 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
1646 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001647
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001648 CHECK_STRING_LENGTH(name1);
1649 CHECK_STRING_LENGTH(name2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 ENTER_TCL
1651 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1652 ENTER_OVERLAP
1653 if (code == TCL_ERROR)
1654 res = Tkinter_Error(self);
1655 else {
1656 Py_INCREF(Py_None);
1657 res = Py_None;
1658 }
1659 LEAVE_OVERLAP_TCL
1660 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001661}
1662
1663static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001664Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001665{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001667}
1668
1669static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001670Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001671{
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +03001672 return var_invoke(UnsetVar, self, args,
1673 TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001674}
1675
Barry Warsawfa701a81997-01-16 00:15:11 +00001676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677
Guido van Rossum18468821994-06-20 07:49:28 +00001678/** Tcl to Python **/
1679
1680static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001681Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001682{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 char *s;
1684 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 if (PyTuple_Size(args) == 1) {
1687 PyObject* o = PyTuple_GetItem(args, 0);
1688 if (PyLong_Check(o)) {
1689 Py_INCREF(o);
1690 return o;
1691 }
1692 }
1693 if (!PyArg_ParseTuple(args, "s:getint", &s))
1694 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001695 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001696 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1697 return Tkinter_Error(self);
1698 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001699}
1700
1701static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001702Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001703{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001704 char *s;
1705 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001707 if (PyTuple_Size(args) == 1) {
1708 PyObject *o = PyTuple_GetItem(args, 0);
1709 if (PyFloat_Check(o)) {
1710 Py_INCREF(o);
1711 return o;
1712 }
1713 }
1714 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
1715 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001716 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1718 return Tkinter_Error(self);
1719 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001720}
1721
1722static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001723Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 char *s;
1726 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 if (PyTuple_Size(args) == 1) {
1729 PyObject *o = PyTuple_GetItem(args, 0);
1730 if (PyLong_Check(o)) {
1731 Py_INCREF(o);
1732 return o;
1733 }
1734 }
1735 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
1736 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001737 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1739 return Tkinter_Error(self);
1740 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00001741}
1742
1743static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001744Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 char *s;
1747 PyObject *res = NULL;
1748 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
1751 return NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001752
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001753 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 ENTER_TCL
1757 retval = Tcl_ExprString(Tkapp_Interp(self), s);
1758 ENTER_OVERLAP
1759 if (retval == TCL_ERROR)
1760 res = Tkinter_Error(self);
1761 else
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001762 res = unicodeFromTclString(Tkapp_Result(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 LEAVE_OVERLAP_TCL
1764 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001765}
1766
1767static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001768Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001769{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 char *s;
1771 PyObject *res = NULL;
1772 int retval;
1773 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
1776 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001777
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001778 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 ENTER_TCL
1782 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
1783 ENTER_OVERLAP
1784 if (retval == TCL_ERROR)
1785 res = Tkinter_Error(self);
1786 else
1787 res = Py_BuildValue("l", v);
1788 LEAVE_OVERLAP_TCL
1789 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001790}
1791
1792static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001793Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001794{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 char *s;
1796 PyObject *res = NULL;
1797 double v;
1798 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
1801 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001802 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 CHECK_TCL_APPARTMENT;
1804 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
1805 ENTER_TCL
1806 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
1807 ENTER_OVERLAP
1808 PyFPE_END_PROTECT(retval)
1809 if (retval == TCL_ERROR)
1810 res = Tkinter_Error(self);
1811 else
1812 res = Py_BuildValue("d", v);
1813 LEAVE_OVERLAP_TCL
1814 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001815}
1816
1817static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001818Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 char *s;
1821 PyObject *res = NULL;
1822 int retval;
1823 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001824
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
1826 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001827 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 CHECK_TCL_APPARTMENT;
1829 ENTER_TCL
1830 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
1831 ENTER_OVERLAP
1832 if (retval == TCL_ERROR)
1833 res = Tkinter_Error(self);
1834 else
1835 res = Py_BuildValue("i", v);
1836 LEAVE_OVERLAP_TCL
1837 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001838}
1839
Barry Warsawfa701a81997-01-16 00:15:11 +00001840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841
Guido van Rossum18468821994-06-20 07:49:28 +00001842static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001843Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001844{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 char *list;
1846 int argc;
1847 char **argv;
Serhiy Storchaka203eb312013-08-22 17:40:31 +03001848 PyObject *arg, *v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001850
Serhiy Storchaka203eb312013-08-22 17:40:31 +03001851 if (!PyArg_ParseTuple(args, "O:splitlist", &arg))
1852 return NULL;
1853 if (PyTclObject_Check(arg)) {
1854 int objc;
1855 Tcl_Obj **objv;
1856 if (Tcl_ListObjGetElements(Tkapp_Interp(self),
1857 ((PyTclObject*)arg)->value,
1858 &objc, &objv) == TCL_ERROR) {
1859 return Tkinter_Error(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 }
Serhiy Storchaka203eb312013-08-22 17:40:31 +03001861 if (!(v = PyTuple_New(objc)))
1862 return NULL;
1863 for (i = 0; i < objc; i++) {
1864 PyObject *s = FromObj(self, objv[i]);
1865 if (!s || PyTuple_SetItem(v, i, s)) {
1866 Py_DECREF(v);
1867 return NULL;
1868 }
1869 }
1870 return v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 }
Serhiy Storchaka203eb312013-08-22 17:40:31 +03001872 if (PyTuple_Check(arg)) {
1873 Py_INCREF(arg);
1874 return arg;
1875 }
1876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
1878 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001879
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001880 CHECK_STRING_LENGTH(list);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 if (Tcl_SplitList(Tkapp_Interp(self), list,
1882 &argc, &argv) == TCL_ERROR) {
1883 PyMem_Free(list);
1884 return Tkinter_Error(self);
1885 }
Guido van Rossum18468821994-06-20 07:49:28 +00001886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 if (!(v = PyTuple_New(argc)))
1888 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 for (i = 0; i < argc; i++) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001891 PyObject *s = unicodeFromTclString(argv[i]);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 if (!s || PyTuple_SetItem(v, i, s)) {
1893 Py_DECREF(v);
1894 v = NULL;
1895 goto finally;
1896 }
1897 }
Guido van Rossum18468821994-06-20 07:49:28 +00001898
Barry Warsawfa701a81997-01-16 00:15:11 +00001899 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 ckfree(FREECAST argv);
1901 PyMem_Free(list);
1902 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001903}
1904
1905static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001906Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001907{
Serhiy Storchaka203eb312013-08-22 17:40:31 +03001908 PyObject *arg, *v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001910
Serhiy Storchaka203eb312013-08-22 17:40:31 +03001911 if (!PyArg_ParseTuple(args, "O:split", &arg))
1912 return NULL;
1913 if (PyTclObject_Check(arg)) {
1914 Tcl_Obj *value = ((PyTclObject*)arg)->value;
1915 int objc;
1916 Tcl_Obj **objv;
1917 int i;
1918 if (Tcl_ListObjGetElements(Tkapp_Interp(self), value,
1919 &objc, &objv) == TCL_ERROR) {
1920 return FromObj(self, value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 }
Serhiy Storchaka203eb312013-08-22 17:40:31 +03001922 if (objc == 0)
1923 return PyUnicode_FromString("");
1924 if (objc == 1)
1925 return FromObj(self, objv[0]);
1926 if (!(v = PyTuple_New(objc)))
1927 return NULL;
1928 for (i = 0; i < objc; i++) {
1929 PyObject *s = FromObj(self, objv[i]);
1930 if (!s || PyTuple_SetItem(v, i, s)) {
1931 Py_DECREF(v);
1932 return NULL;
1933 }
1934 }
1935 return v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 }
Serhiy Storchaka203eb312013-08-22 17:40:31 +03001937 if (PyTuple_Check(arg))
1938 return SplitObj(arg);
1939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
1941 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001942 CHECK_STRING_LENGTH(list);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 v = Split(list);
1944 PyMem_Free(list);
1945 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001946}
1947
Barry Warsawfa701a81997-01-16 00:15:11 +00001948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949
Guido van Rossum18468821994-06-20 07:49:28 +00001950/** Tcl Command **/
1951
Guido van Rossum00d93061998-05-28 23:06:38 +00001952/* Client data struct */
1953typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 PyObject *self;
1955 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001956} PythonCmd_ClientData;
1957
1958static int
Fred Drake509d79a2000-07-08 04:04:38 +00001959PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001960{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 errorInCmd = 1;
1962 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1963 LEAVE_PYTHON
1964 return TCL_ERROR;
Guido van Rossum00d93061998-05-28 23:06:38 +00001965}
1966
Guido van Rossum18468821994-06-20 07:49:28 +00001967/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001968 * function or method.
1969 */
Guido van Rossum18468821994-06-20 07:49:28 +00001970static int
Fred Drake509d79a2000-07-08 04:04:38 +00001971PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Brett Cannonb94767f2011-02-22 20:15:44 +00001974 PyObject *func, *arg, *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 int i, rv;
1976 Tcl_Obj *obj_res;
Guido van Rossum18468821994-06-20 07:49:28 +00001977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 /* TBD: no error checking here since we know, via the
1981 * Tkapp_CreateCommand() that the client data is a two-tuple
1982 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 /* Create argument list (argv1, ..., argvN) */
1986 if (!(arg = PyTuple_New(argc - 1)))
1987 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001989 for (i = 0; i < (argc - 1); i++) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001990 PyObject *s = unicodeFromTclString(argv[i + 1]);
1991 if (!s || PyTuple_SetItem(arg, i, s)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 Py_DECREF(arg);
1993 return PythonCmd_Error(interp);
1994 }
1995 }
1996 res = PyEval_CallObject(func, arg);
1997 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 if (res == NULL)
2000 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00002001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 obj_res = AsObj(res);
2003 if (obj_res == NULL) {
2004 Py_DECREF(res);
2005 return PythonCmd_Error(interp);
2006 }
2007 else {
2008 Tcl_SetObjResult(interp, obj_res);
2009 rv = TCL_OK;
2010 }
Guido van Rossum2834b972000-10-06 16:58:26 +00002011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002012 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00002013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 LEAVE_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002017}
2018
2019static void
Fred Drake509d79a2000-07-08 04:04:38 +00002020PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002021{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Guido van Rossum00d93061998-05-28 23:06:38 +00002023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 ENTER_PYTHON
2025 Py_XDECREF(data->self);
2026 Py_XDECREF(data->func);
2027 PyMem_DEL(data);
2028 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002029}
2030
Barry Warsawfa701a81997-01-16 00:15:11 +00002031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002032
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002033
Benjamin Peterson5879d412009-03-30 14:51:56 +00002034#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002035TCL_DECLARE_MUTEX(command_mutex)
2036
2037typedef struct CommandEvent{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002038 Tcl_Event ev;
2039 Tcl_Interp* interp;
2040 char *name;
2041 int create;
2042 int *status;
2043 ClientData *data;
2044 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002045} CommandEvent;
2046
2047static int
2048Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002049{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 if (ev->create)
2051 *ev->status = Tcl_CreateCommand(
2052 ev->interp, ev->name, PythonCmd,
2053 ev->data, PythonCmdDelete) == NULL;
2054 else
2055 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2056 Tcl_MutexLock(&command_mutex);
2057 Tcl_ConditionNotify(ev->done);
2058 Tcl_MutexUnlock(&command_mutex);
2059 return 1;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002060}
Benjamin Peterson5879d412009-03-30 14:51:56 +00002061#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002062
2063static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002064Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002065{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 TkappObject *self = (TkappObject*)selfptr;
2067 PythonCmd_ClientData *data;
2068 char *cmdName;
2069 PyObject *func;
2070 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002072 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
2073 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03002074 CHECK_STRING_LENGTH(cmdName);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 if (!PyCallable_Check(func)) {
2076 PyErr_SetString(PyExc_TypeError, "command not callable");
2077 return NULL;
2078 }
Guido van Rossum18468821994-06-20 07:49:28 +00002079
Martin v. Löwisa9656492003-03-30 08:44:58 +00002080#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
2082 !WaitForMainloop(self))
2083 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002084#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 data = PyMem_NEW(PythonCmd_ClientData, 1);
2087 if (!data)
2088 return PyErr_NoMemory();
2089 Py_INCREF(self);
2090 Py_INCREF(func);
2091 data->self = selfptr;
2092 data->func = func;
Benjamin Peterson5879d412009-03-30 14:51:56 +00002093#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2095 Tcl_Condition cond = NULL;
Serhiy Storchaka07940882014-09-11 10:38:54 +03002096 CommandEvent *ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent));
2097 if (ev == NULL) {
2098 PyErr_NoMemory();
2099 PyMem_DEL(data);
2100 return NULL;
2101 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2103 ev->interp = self->interp;
2104 ev->create = 1;
2105 ev->name = cmdName;
2106 ev->data = (ClientData)data;
2107 ev->status = &err;
2108 ev->done = &cond;
2109 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
2110 Tcl_ConditionFinalize(&cond);
2111 }
2112 else
Benjamin Peterson5879d412009-03-30 14:51:56 +00002113#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 {
2115 ENTER_TCL
2116 err = Tcl_CreateCommand(
2117 Tkapp_Interp(self), cmdName, PythonCmd,
2118 (ClientData)data, PythonCmdDelete) == NULL;
2119 LEAVE_TCL
2120 }
2121 if (err) {
2122 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
2123 PyMem_DEL(data);
2124 return NULL;
2125 }
Guido van Rossum18468821994-06-20 07:49:28 +00002126
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002127 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002128}
2129
Barry Warsawfa701a81997-01-16 00:15:11 +00002130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131
Guido van Rossum18468821994-06-20 07:49:28 +00002132static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002133Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 TkappObject *self = (TkappObject*)selfptr;
2136 char *cmdName;
2137 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
2140 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03002141 CHECK_STRING_LENGTH(cmdName);
Benjamin Peterson5879d412009-03-30 14:51:56 +00002142
2143#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002144 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2145 Tcl_Condition cond = NULL;
2146 CommandEvent *ev;
Serhiy Storchaka07940882014-09-11 10:38:54 +03002147 ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent));
2148 if (ev == NULL) {
2149 PyErr_NoMemory();
2150 return NULL;
2151 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002152 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2153 ev->interp = self->interp;
2154 ev->create = 0;
2155 ev->name = cmdName;
2156 ev->status = &err;
2157 ev->done = &cond;
2158 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
2159 &command_mutex);
2160 Tcl_ConditionFinalize(&cond);
2161 }
2162 else
Benjamin Peterson5879d412009-03-30 14:51:56 +00002163#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 {
2165 ENTER_TCL
2166 err = Tcl_DeleteCommand(self->interp, cmdName);
2167 LEAVE_TCL
2168 }
2169 if (err == -1) {
2170 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2171 return NULL;
2172 }
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002173 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002174}
2175
Barry Warsawfa701a81997-01-16 00:15:11 +00002176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177
Guido van Rossum00d93061998-05-28 23:06:38 +00002178#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002179/** File Handler **/
2180
Guido van Rossum00d93061998-05-28 23:06:38 +00002181typedef struct _fhcdata {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 PyObject *func;
2183 PyObject *file;
2184 int id;
2185 struct _fhcdata *next;
Guido van Rossum00d93061998-05-28 23:06:38 +00002186} FileHandler_ClientData;
2187
2188static FileHandler_ClientData *HeadFHCD;
2189
2190static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002191NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002193 FileHandler_ClientData *p;
2194 p = PyMem_NEW(FileHandler_ClientData, 1);
2195 if (p != NULL) {
2196 Py_XINCREF(func);
2197 Py_XINCREF(file);
2198 p->func = func;
2199 p->file = file;
2200 p->id = id;
2201 p->next = HeadFHCD;
2202 HeadFHCD = p;
2203 }
2204 return p;
Guido van Rossum00d93061998-05-28 23:06:38 +00002205}
2206
2207static void
Fred Drake509d79a2000-07-08 04:04:38 +00002208DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002210 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002212 pp = &HeadFHCD;
2213 while ((p = *pp) != NULL) {
2214 if (p->id == id) {
2215 *pp = p->next;
2216 Py_XDECREF(p->func);
2217 Py_XDECREF(p->file);
2218 PyMem_DEL(p);
2219 }
2220 else
2221 pp = &p->next;
2222 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002223}
2224
Guido van Rossuma597dde1995-01-10 20:56:29 +00002225static void
Fred Drake509d79a2000-07-08 04:04:38 +00002226FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002227{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
2229 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 ENTER_PYTHON
2232 func = data->func;
2233 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 arg = Py_BuildValue("(Oi)", file, (long) mask);
2236 res = PyEval_CallObject(func, arg);
2237 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 if (res == NULL) {
2240 errorInCmd = 1;
2241 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2242 }
2243 Py_XDECREF(res);
2244 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002245}
2246
Guido van Rossum18468821994-06-20 07:49:28 +00002247static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002248Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2249 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00002250{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002251 FileHandler_ClientData *data;
2252 PyObject *file, *func;
2253 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00002254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2256 &file, &mask, &func))
2257 return NULL;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002259 CHECK_TCL_APPARTMENT;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 tfile = PyObject_AsFileDescriptor(file);
2262 if (tfile < 0)
2263 return NULL;
2264 if (!PyCallable_Check(func)) {
2265 PyErr_SetString(PyExc_TypeError, "bad argument list");
2266 return NULL;
2267 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002269 data = NewFHCD(func, file, tfile);
2270 if (data == NULL)
2271 return NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 /* Ought to check for null Tcl_File object... */
2274 ENTER_TCL
2275 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
2276 LEAVE_TCL
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002277 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002278}
2279
2280static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002281Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002282{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 PyObject *file;
2284 int tfile;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002286 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
2287 return NULL;
Neal Norwitz12e22172003-03-03 21:16:39 +00002288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 CHECK_TCL_APPARTMENT;
Neal Norwitz12e22172003-03-03 21:16:39 +00002290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 tfile = PyObject_AsFileDescriptor(file);
2292 if (tfile < 0)
2293 return NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002297 /* Ought to check for null Tcl_File object... */
2298 ENTER_TCL
2299 Tcl_DeleteFileHandler(tfile);
2300 LEAVE_TCL
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002301 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002302}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002303#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002306/**** Tktt Object (timer token) ****/
2307
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03002308static PyObject *Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002309
Guido van Rossum00d93061998-05-28 23:06:38 +00002310typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002311 PyObject_HEAD
2312 Tcl_TimerToken token;
2313 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002314} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002315
2316static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002317Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002319 TkttObject *v = (TkttObject *)self;
2320 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002322 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
2323 return NULL;
2324 if (v->token != NULL) {
2325 Tcl_DeleteTimerHandler(v->token);
2326 v->token = NULL;
2327 }
2328 if (func != NULL) {
2329 v->func = NULL;
2330 Py_DECREF(func);
2331 Py_DECREF(v); /* See Tktt_New() */
2332 }
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002333 Py_RETURN_NONE;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002334}
2335
2336static PyMethodDef Tktt_methods[] =
2337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002338 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
2339 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002340};
2341
2342static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002343Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 TkttObject *v;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002346
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03002347 v = PyObject_New(TkttObject, (PyTypeObject *) Tktt_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002348 if (v == NULL)
2349 return NULL;
Antoine Pitrou584e8152013-08-11 00:22:30 +02002350 Py_INCREF(Tktt_Type);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002352 Py_INCREF(func);
2353 v->token = NULL;
2354 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002356 /* Extra reference, deleted when called or when handler is deleted */
2357 Py_INCREF(v);
2358 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002359}
2360
2361static void
Fred Drake509d79a2000-07-08 04:04:38 +00002362Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 TkttObject *v = (TkttObject *)self;
2365 PyObject *func = v->func;
Antoine Pitrou584e8152013-08-11 00:22:30 +02002366 PyObject *tp = (PyObject *) Py_TYPE(self);
Guido van Rossum00d93061998-05-28 23:06:38 +00002367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002368 Py_XDECREF(func);
Guido van Rossum00d93061998-05-28 23:06:38 +00002369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002370 PyObject_Del(self);
Antoine Pitrou584e8152013-08-11 00:22:30 +02002371 Py_DECREF(tp);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002372}
2373
Guido van Rossum597ac201998-05-12 14:36:19 +00002374static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002375Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002376{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377 TkttObject *v = (TkttObject *)self;
Victor Stinner6ced7c42011-03-21 18:15:42 +01002378 return PyUnicode_FromFormat("<tktimertoken at %p%s>",
2379 v,
2380 v->func == NULL ? ", handler deleted" : "");
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002381}
2382
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03002383static PyType_Slot Tktt_Type_slots[] = {
2384 {Py_tp_dealloc, Tktt_Dealloc},
2385 {Py_tp_repr, Tktt_Repr},
2386 {Py_tp_methods, Tktt_methods},
2387 {0, 0}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002388};
2389
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03002390static PyType_Spec Tktt_Type_spec = {
2391 "tktimertoken",
2392 sizeof(TkttObject),
2393 0,
2394 Py_TPFLAGS_DEFAULT,
2395 Tktt_Type_slots,
2396};
Barry Warsawfa701a81997-01-16 00:15:11 +00002397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002399/** Timer Handler **/
2400
2401static void
Fred Drake509d79a2000-07-08 04:04:38 +00002402TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 TkttObject *v = (TkttObject *)clientData;
2405 PyObject *func = v->func;
2406 PyObject *res;
Guido van Rossum00d93061998-05-28 23:06:38 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 if (func == NULL)
2409 return;
Guido van Rossum00d93061998-05-28 23:06:38 +00002410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 res = PyEval_CallObject(func, NULL);
2416 Py_DECREF(func);
2417 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 if (res == NULL) {
2420 errorInCmd = 1;
2421 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2422 }
2423 else
2424 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002427}
2428
2429static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002430Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002432 int milliseconds;
2433 PyObject *func;
2434 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2437 &milliseconds, &func))
2438 return NULL;
2439 if (!PyCallable_Check(func)) {
2440 PyErr_SetString(PyExc_TypeError, "bad argument list");
2441 return NULL;
2442 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 CHECK_TCL_APPARTMENT;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 v = Tktt_New(func);
2447 if (v) {
2448 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2449 (ClientData)v);
2450 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002453}
2454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455
Guido van Rossum18468821994-06-20 07:49:28 +00002456/** Event Loop **/
2457
Guido van Rossum18468821994-06-20 07:49:28 +00002458static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00002459Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002461 int threshold = 0;
2462 TkappObject *self = (TkappObject*)selfptr;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002463#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002464 PyThreadState *tstate = PyThreadState_Get();
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002465#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
2468 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002470 CHECK_TCL_APPARTMENT;
2471 self->dispatching = 1;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002473 quitMainLoop = 0;
2474 while (Tk_GetNumMainWindows() > threshold &&
2475 !quitMainLoop &&
2476 !errorInCmd)
2477 {
2478 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002479
2480#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 if (self->threaded) {
2482 /* Allow other Python threads to run. */
2483 ENTER_TCL
2484 result = Tcl_DoOneEvent(0);
2485 LEAVE_TCL
2486 }
2487 else {
2488 Py_BEGIN_ALLOW_THREADS
2489 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2490 tcl_tstate = tstate;
2491 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2492 tcl_tstate = NULL;
2493 if(tcl_lock)PyThread_release_lock(tcl_lock);
2494 if (result == 0)
2495 Sleep(Tkinter_busywaitinterval);
2496 Py_END_ALLOW_THREADS
2497 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002498#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002499 result = Tcl_DoOneEvent(0);
Guido van Rossum5b020781997-08-19 01:00:50 +00002500#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 if (PyErr_CheckSignals() != 0) {
2503 self->dispatching = 0;
2504 return NULL;
2505 }
2506 if (result < 0)
2507 break;
2508 }
2509 self->dispatching = 0;
2510 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 if (errorInCmd) {
2513 errorInCmd = 0;
2514 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2515 excInCmd = valInCmd = trbInCmd = NULL;
2516 return NULL;
2517 }
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002518 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002519}
2520
2521static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002522Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00002523{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002524 int flags = 0;
2525 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00002526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002527 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
2528 return NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002530 ENTER_TCL
2531 rv = Tcl_DoOneEvent(flags);
2532 LEAVE_TCL
2533 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002534}
2535
2536static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002537Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002538{
2539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002540 if (!PyArg_ParseTuple(args, ":quit"))
2541 return NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002543 quitMainLoop = 1;
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002544 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002545}
2546
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002547static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002548Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002549{
2550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002551 if (!PyArg_ParseTuple(args, ":interpaddr"))
2552 return NULL;
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002553
Victor Stinnere1040e22013-09-05 00:22:24 +02002554 return PyLong_FromVoidPtr(Tkapp_Interp(self));
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002555}
2556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002557static PyObject *
David Aschere2b4b322004-02-18 05:59:53 +00002558Tkapp_TkInit(PyObject *self, PyObject *args)
2559{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002560 Tcl_Interp *interp = Tkapp_Interp(self);
2561 const char * _tk_exists = NULL;
2562 int err;
David Aschere2b4b322004-02-18 05:59:53 +00002563
Guilherme Polob681df42009-02-09 22:33:59 +00002564#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002565 /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the
2566 * first call failed.
2567 * To avoid the deadlock, we just refuse the second call through
2568 * a static variable.
2569 */
2570 if (tk_load_failed) {
2571 PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG);
2572 return NULL;
2573 }
Guilherme Polob681df42009-02-09 22:33:59 +00002574#endif
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002576 /* We want to guard against calling Tk_Init() multiple times */
2577 CHECK_TCL_APPARTMENT;
2578 ENTER_TCL
2579 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2580 ENTER_OVERLAP
2581 if (err == TCL_ERROR) {
2582 /* This sets an exception, but we cannot return right
2583 away because we need to exit the overlap first. */
2584 Tkinter_Error(self);
2585 } else {
2586 _tk_exists = Tkapp_Result(self);
2587 }
2588 LEAVE_OVERLAP_TCL
2589 if (err == TCL_ERROR) {
2590 return NULL;
2591 }
2592 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2593 if (Tk_Init(interp) == TCL_ERROR) {
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +03002594 PyErr_SetString(Tkinter_TclError,
2595 Tcl_GetStringResult(Tkapp_Interp(self)));
Guilherme Polob681df42009-02-09 22:33:59 +00002596#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 tk_load_failed = 1;
Guilherme Polob681df42009-02-09 22:33:59 +00002598#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002599 return NULL;
2600 }
2601 }
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002602 Py_RETURN_NONE;
David Aschere2b4b322004-02-18 05:59:53 +00002603}
Barry Warsawfa701a81997-01-16 00:15:11 +00002604
Martin v. Löwisffad6332002-11-26 09:28:05 +00002605static PyObject *
2606Tkapp_WantObjects(PyObject *self, PyObject *args)
2607{
2608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002609 int wantobjects = -1;
2610 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
2611 return NULL;
2612 if (wantobjects == -1)
2613 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
2614 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002615
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002616 Py_RETURN_NONE;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002617}
2618
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002619static PyObject *
2620Tkapp_WillDispatch(PyObject *self, PyObject *args)
2621{
2622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002623 ((TkappObject*)self)->dispatching = 1;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002624
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002625 Py_RETURN_NONE;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00002626}
Martin v. Löwisffad6332002-11-26 09:28:05 +00002627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002628
Guido van Rossum18468821994-06-20 07:49:28 +00002629/**** Tkapp Method List ****/
2630
2631static PyMethodDef Tkapp_methods[] =
2632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
2634 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
2635 {"call", Tkapp_Call, METH_VARARGS},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002636 {"eval", Tkapp_Eval, METH_VARARGS},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002637 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2638 {"record", Tkapp_Record, METH_VARARGS},
2639 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2640 {"setvar", Tkapp_SetVar, METH_VARARGS},
2641 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2642 {"getvar", Tkapp_GetVar, METH_VARARGS},
2643 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2644 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2645 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2646 {"getint", Tkapp_GetInt, METH_VARARGS},
2647 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2648 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2649 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2650 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2651 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2652 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2653 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2654 {"split", Tkapp_Split, METH_VARARGS},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002655 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2656 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002657#ifdef HAVE_CREATEFILEHANDLER
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002658 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2659 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002660#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002661 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2662 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2663 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2664 {"quit", Tkapp_Quit, METH_VARARGS},
2665 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
2666 {"loadtk", Tkapp_TkInit, METH_NOARGS},
2667 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002668};
2669
Barry Warsawfa701a81997-01-16 00:15:11 +00002670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671
Guido van Rossum18468821994-06-20 07:49:28 +00002672/**** Tkapp Type Methods ****/
2673
2674static void
Fred Drake509d79a2000-07-08 04:04:38 +00002675Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002676{
Antoine Pitrou584e8152013-08-11 00:22:30 +02002677 PyObject *tp = (PyObject *) Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002678 /*CHECK_TCL_APPARTMENT;*/
2679 ENTER_TCL
2680 Tcl_DeleteInterp(Tkapp_Interp(self));
2681 LEAVE_TCL
2682 PyObject_Del(self);
Antoine Pitrou584e8152013-08-11 00:22:30 +02002683 Py_DECREF(tp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002684 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002685}
2686
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03002687static PyType_Slot Tkapp_Type_slots[] = {
2688 {Py_tp_dealloc, Tkapp_Dealloc},
2689 {Py_tp_methods, Tkapp_methods},
2690 {0, 0}
2691};
2692
2693
2694static PyType_Spec Tkapp_Type_spec = {
2695 "tkapp",
2696 sizeof(TkappObject),
2697 0,
2698 Py_TPFLAGS_DEFAULT,
2699 Tkapp_Type_slots,
Guido van Rossum18468821994-06-20 07:49:28 +00002700};
2701
Barry Warsawfa701a81997-01-16 00:15:11 +00002702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002703
Guido van Rossum18468821994-06-20 07:49:28 +00002704/**** Tkinter Module ****/
2705
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002706typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002707 PyObject* tuple;
2708 int size; /* current size */
2709 int maxsize; /* allocated size */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002710} FlattenContext;
2711
2712static int
2713_bump(FlattenContext* context, int size)
2714{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002715 /* expand tuple to hold (at least) size new items.
2716 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002718 int maxsize = context->maxsize * 2;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002720 if (maxsize < context->size + size)
2721 maxsize = context->size + size;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002723 context->maxsize = maxsize;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002724
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002725 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002726}
2727
2728static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002729_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002730{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002731 /* add tuple or list to argument tuple (recursively) */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002733 int i, size;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002735 if (depth > 1000) {
2736 PyErr_SetString(PyExc_ValueError,
2737 "nesting too deep in _flatten");
2738 return 0;
2739 } else if (PyList_Check(item)) {
2740 size = PyList_GET_SIZE(item);
2741 /* preallocate (assume no nesting) */
2742 if (context->size + size > context->maxsize &&
2743 !_bump(context, size))
2744 return 0;
2745 /* copy items to output tuple */
2746 for (i = 0; i < size; i++) {
2747 PyObject *o = PyList_GET_ITEM(item, i);
2748 if (PyList_Check(o) || PyTuple_Check(o)) {
2749 if (!_flatten1(context, o, depth + 1))
2750 return 0;
2751 } else if (o != Py_None) {
2752 if (context->size + 1 > context->maxsize &&
2753 !_bump(context, 1))
2754 return 0;
2755 Py_INCREF(o);
2756 PyTuple_SET_ITEM(context->tuple,
2757 context->size++, o);
2758 }
2759 }
2760 } else if (PyTuple_Check(item)) {
2761 /* same, for tuples */
2762 size = PyTuple_GET_SIZE(item);
2763 if (context->size + size > context->maxsize &&
2764 !_bump(context, size))
2765 return 0;
2766 for (i = 0; i < size; i++) {
2767 PyObject *o = PyTuple_GET_ITEM(item, i);
2768 if (PyList_Check(o) || PyTuple_Check(o)) {
2769 if (!_flatten1(context, o, depth + 1))
2770 return 0;
2771 } else if (o != Py_None) {
2772 if (context->size + 1 > context->maxsize &&
2773 !_bump(context, 1))
2774 return 0;
2775 Py_INCREF(o);
2776 PyTuple_SET_ITEM(context->tuple,
2777 context->size++, o);
2778 }
2779 }
2780 } else {
2781 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2782 return 0;
2783 }
2784 return 1;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002785}
2786
2787static PyObject *
2788Tkinter_Flatten(PyObject* self, PyObject* args)
2789{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002790 FlattenContext context;
2791 PyObject* item;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002793 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2794 return NULL;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 context.maxsize = PySequence_Size(item);
2797 if (context.maxsize < 0)
2798 return NULL;
2799 if (context.maxsize == 0)
2800 return PyTuple_New(0);
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002802 context.tuple = PyTuple_New(context.maxsize);
2803 if (!context.tuple)
2804 return NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002806 context.size = 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002808 if (!_flatten1(&context, item,0))
2809 return NULL;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002810
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002811 if (_PyTuple_Resize(&context.tuple, context.size))
2812 return NULL;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002814 return context.tuple;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002815}
2816
Guido van Rossum18468821994-06-20 07:49:28 +00002817static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002818Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002820 char *screenName = NULL;
2821 char *baseName = NULL; /* XXX this is not used anymore;
2822 try getting rid of it. */
2823 char *className = NULL;
2824 int interactive = 0;
2825 int wantobjects = 0;
2826 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
2827 int sync = 0; /* pass -sync to wish */
2828 char *use = NULL; /* pass -use to wish */
Guido van Rossum18468821994-06-20 07:49:28 +00002829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002830 className = "Tk";
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002832 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
2833 &screenName, &baseName, &className,
2834 &interactive, &wantobjects, &wantTk,
2835 &sync, &use))
2836 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03002837 CHECK_STRING_LENGTH(screenName);
2838 CHECK_STRING_LENGTH(baseName);
2839 CHECK_STRING_LENGTH(className);
2840 CHECK_STRING_LENGTH(use);
Guido van Rossum18468821994-06-20 07:49:28 +00002841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002842 return (PyObject *) Tkapp_New(screenName, className,
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +03002843 interactive, wantobjects, wantTk,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002844 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00002845}
2846
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002847static PyObject *
2848Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2849{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 int new_val;
2851 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2852 return NULL;
2853 if (new_val < 0) {
2854 PyErr_SetString(PyExc_ValueError,
2855 "busywaitinterval must be >= 0");
2856 return NULL;
2857 }
2858 Tkinter_busywaitinterval = new_val;
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002859 Py_RETURN_NONE;
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002860}
2861
2862static char setbusywaitinterval_doc[] =
2863"setbusywaitinterval(n) -> None\n\
2864\n\
2865Set the busy-wait interval in milliseconds between successive\n\
2866calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2867It should be set to a divisor of the maximum time between\n\
2868frames in an animation.";
2869
2870static PyObject *
2871Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002873 return PyLong_FromLong(Tkinter_busywaitinterval);
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00002874}
2875
2876static char getbusywaitinterval_doc[] =
2877"getbusywaitinterval() -> int\n\
2878\n\
2879Return the current busy-wait interval between successive\n\
2880calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2881
Guido van Rossum18468821994-06-20 07:49:28 +00002882static PyMethodDef moduleMethods[] =
2883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002884 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2885 {"create", Tkinter_Create, METH_VARARGS},
2886 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2887 setbusywaitinterval_doc},
2888 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2889 METH_NOARGS, getbusywaitinterval_doc},
2890 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002891};
2892
Guido van Rossum7bf15641998-05-22 18:28:17 +00002893#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002894
2895static int stdin_ready = 0;
2896
Guido van Rossumad4db171998-06-13 13:56:28 +00002897#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002898static void
Fred Drake509d79a2000-07-08 04:04:38 +00002899MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002900{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002901 stdin_ready = 1;
Guido van Rossum7bf15641998-05-22 18:28:17 +00002902}
Guido van Rossumad4db171998-06-13 13:56:28 +00002903#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002904
Martin v. Löwisa9656492003-03-30 08:44:58 +00002905#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002906static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002907#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002908
Guido van Rossum18468821994-06-20 07:49:28 +00002909static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002910EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002911{
Guido van Rossumad4db171998-06-13 13:56:28 +00002912#ifndef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002913 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002914#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002915#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002916 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002917#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002918 stdin_ready = 0;
2919 errorInCmd = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002920#ifndef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002921 tfile = fileno(stdin);
2922 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002923#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002924 while (!errorInCmd && !stdin_ready) {
2925 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002926#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002927 if (_kbhit()) {
2928 stdin_ready = 1;
2929 break;
2930 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002931#endif
2932#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002933 Py_BEGIN_ALLOW_THREADS
2934 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2935 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002937 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002939 tcl_tstate = NULL;
2940 if(tcl_lock)PyThread_release_lock(tcl_lock);
2941 if (result == 0)
2942 Sleep(Tkinter_busywaitinterval);
2943 Py_END_ALLOW_THREADS
Guido van Rossum00d93061998-05-28 23:06:38 +00002944#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002945 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002946#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002948 if (result < 0)
2949 break;
2950 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002951#ifndef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002952 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002953#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002954 if (errorInCmd) {
2955 errorInCmd = 0;
2956 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2957 excInCmd = valInCmd = trbInCmd = NULL;
2958 PyErr_Print();
2959 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002960#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002961 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002962#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002963 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002964}
Guido van Rossum18468821994-06-20 07:49:28 +00002965
Guido van Rossum00d93061998-05-28 23:06:38 +00002966#endif
2967
Guido van Rossum7bf15641998-05-22 18:28:17 +00002968static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002969EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002970{
Guido van Rossum00d93061998-05-28 23:06:38 +00002971#ifdef WAIT_FOR_STDIN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002972 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002973#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002974 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002975#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002976 PyOS_InputHook = EventHook;
2977 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002978#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002979}
2980
2981static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002982DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002983{
Guido van Rossum00d93061998-05-28 23:06:38 +00002984#ifdef WAIT_FOR_STDIN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002985 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2986 PyOS_InputHook = NULL;
2987 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002988#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002989}
2990
Barry Warsawfa701a81997-01-16 00:15:11 +00002991
Martin v. Löwis1a214512008-06-11 05:26:20 +00002992static struct PyModuleDef _tkintermodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002993 PyModuleDef_HEAD_INIT,
2994 "_tkinter",
2995 NULL,
2996 -1,
2997 moduleMethods,
2998 NULL,
2999 NULL,
3000 NULL,
3001 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00003002};
3003
Mark Hammond62b1ab12002-07-23 06:31:15 +00003004PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00003005PyInit__tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003006{
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003007 PyObject *m, *uexe, *cexe, *o;
Guido van Rossum18468821994-06-20 07:49:28 +00003008
Guido van Rossum00d93061998-05-28 23:06:38 +00003009#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003010 tcl_lock = PyThread_allocate_lock();
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003011 if (tcl_lock == NULL)
3012 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00003013#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003015 m = PyModule_Create(&_tkintermodule);
3016 if (m == NULL)
3017 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00003018
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003019 o = PyErr_NewException("_tkinter.TclError", NULL, NULL);
3020 if (o == NULL) {
Jesus Ceaef86d122012-07-19 21:18:07 +02003021 Py_DECREF(m);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003022 return NULL;
Jesus Ceaef86d122012-07-19 21:18:07 +02003023 }
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003024 Py_INCREF(o);
3025 if (PyModule_AddObject(m, "TclError", o)) {
3026 Py_DECREF(o);
3027 Py_DECREF(m);
3028 return NULL;
3029 }
3030 Tkinter_TclError = o;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003031
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003032 if (PyModule_AddIntConstant(m, "READABLE", TCL_READABLE)) {
3033 Py_DECREF(m);
3034 return NULL;
3035 }
3036 if (PyModule_AddIntConstant(m, "WRITABLE", TCL_WRITABLE)) {
3037 Py_DECREF(m);
3038 return NULL;
3039 }
3040 if (PyModule_AddIntConstant(m, "EXCEPTION", TCL_EXCEPTION)) {
3041 Py_DECREF(m);
3042 return NULL;
3043 }
3044 if (PyModule_AddIntConstant(m, "WINDOW_EVENTS", TCL_WINDOW_EVENTS)) {
3045 Py_DECREF(m);
3046 return NULL;
3047 }
3048 if (PyModule_AddIntConstant(m, "FILE_EVENTS", TCL_FILE_EVENTS)) {
3049 Py_DECREF(m);
3050 return NULL;
3051 }
3052 if (PyModule_AddIntConstant(m, "TIMER_EVENTS", TCL_TIMER_EVENTS)) {
3053 Py_DECREF(m);
3054 return NULL;
3055 }
3056 if (PyModule_AddIntConstant(m, "IDLE_EVENTS", TCL_IDLE_EVENTS)) {
3057 Py_DECREF(m);
3058 return NULL;
3059 }
3060 if (PyModule_AddIntConstant(m, "ALL_EVENTS", TCL_ALL_EVENTS)) {
3061 Py_DECREF(m);
3062 return NULL;
3063 }
3064 if (PyModule_AddIntConstant(m, "DONT_WAIT", TCL_DONT_WAIT)) {
3065 Py_DECREF(m);
3066 return NULL;
3067 }
3068 if (PyModule_AddStringConstant(m, "TK_VERSION", TK_VERSION)) {
3069 Py_DECREF(m);
3070 return NULL;
3071 }
3072 if (PyModule_AddStringConstant(m, "TCL_VERSION", TCL_VERSION)) {
3073 Py_DECREF(m);
3074 return NULL;
3075 }
3076
3077 o = PyType_FromSpec(&Tkapp_Type_spec);
3078 if (o == NULL) {
3079 Py_DECREF(m);
3080 return NULL;
3081 }
3082 if (PyModule_AddObject(m, "TkappType", o)) {
3083 Py_DECREF(o);
3084 Py_DECREF(m);
3085 return NULL;
3086 }
3087 Tkapp_Type = o;
3088
3089 o = PyType_FromSpec(&Tktt_Type_spec);
3090 if (o == NULL) {
3091 Py_DECREF(m);
3092 return NULL;
3093 }
3094 if (PyModule_AddObject(m, "TkttType", o)) {
3095 Py_DECREF(o);
3096 Py_DECREF(m);
3097 return NULL;
3098 }
3099 Tktt_Type = o;
3100
3101 o = PyType_FromSpec(&PyTclObject_Type_spec);
3102 if (o == NULL) {
3103 Py_DECREF(m);
3104 return NULL;
3105 }
3106 if (PyModule_AddObject(m, "Tcl_Obj", o)) {
3107 Py_DECREF(o);
3108 Py_DECREF(m);
3109 return NULL;
3110 }
3111 PyTclObject_Type = o;
Jack Jansencb852442001-12-09 23:15:56 +00003112
3113#ifdef TK_AQUA
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003114 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3115 * start waking up. Note that Tcl_FindExecutable will do this, this
3116 * code must be above it! The original warning from
3117 * tkMacOSXAppInit.c is copied below.
3118 *
3119 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3120 * Tcl interpreter for now. It probably should work to do this
3121 * in the other order, but for now it doesn't seem to.
3122 *
3123 */
3124 Tk_MacOSXSetupTkNotifier();
Jack Jansencb852442001-12-09 23:15:56 +00003125#endif
3126
3127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003128 /* This helps the dynamic loader; in Unicode aware Tcl versions
3129 it also helps Tcl find its encodings. */
3130 uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1);
3131 if (uexe) {
Victor Stinnerae6265f2010-05-15 16:27:27 +00003132 cexe = PyUnicode_EncodeFSDefault(uexe);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003133 if (cexe)
3134 Tcl_FindExecutable(PyBytes_AsString(cexe));
3135 Py_XDECREF(cexe);
3136 Py_DECREF(uexe);
3137 }
Guido van Rossume187b0e2000-03-27 21:46:29 +00003138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003139 if (PyErr_Occurred()) {
3140 Py_DECREF(m);
3141 return NULL;
3142 }
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003143
Guido van Rossum43ff8681998-07-14 18:02:13 +00003144#if 0
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003145 /* This was not a good idea; through <Destroy> bindings,
3146 Tcl_Finalize() may invoke Python code but at that point the
3147 interpreter and thread state have already been destroyed! */
3148 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003149#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003150 return m;
Guido van Rossum18468821994-06-20 07:49:28 +00003151}