blob: 3e96aa0cd50c64cbe95a1c1fed7f7e046cf900a1 [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
Serhiy Storchaka6716d602014-07-30 19:19:21 +030012 Only Tcl/Tk 8.4 and later are supported. Older versions are not
13 supported. Use Python 3.4 or older if you cannot upgrade your
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000014 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
Serhiy Storchaka26861b02015-02-16 20:52:17 +020024#define PY_SSIZE_T_CLEAN
Guido van Rossum35d43371997-08-02 00:09:09 +000025
Guido van Rossum9722ad81995-09-22 23:49:28 +000026#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000027#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000028
Guido van Rossum00d93061998-05-28 23:06:38 +000029#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000030#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000031#endif
32
Guido van Rossum2a5119b1998-05-29 01:28:40 +000033#ifdef MS_WINDOWS
34#include <windows.h>
35#endif
36
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +030037#define CHECK_SIZE(size, elemsize) \
Serhiy Storchaka26861b02015-02-16 20:52:17 +020038 ((size_t)(size) <= Py_MIN((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize)))
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +030039
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +000040/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
41 it always; if Tcl is not threaded, the thread functions in
42 Tcl are empty. */
43#define TCL_THREADS
44
Jack Jansencb852442001-12-09 23:15:56 +000045#ifdef TK_FRAMEWORK
46#include <Tcl/tcl.h>
47#include <Tk/tk.h>
48#else
Guido van Rossum18468821994-06-20 07:49:28 +000049#include <tcl.h>
50#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000051#endif
Guido van Rossum18468821994-06-20 07:49:28 +000052
Guilherme Polo2d87e422009-04-10 22:19:09 +000053#include "tkinter.h"
54
Serhiy Storchaka71b49dd2015-04-22 10:59:32 +030055#if TK_HEX_VERSION < 0x08040200
Serhiy Storchaka6716d602014-07-30 19:19:21 +030056#error "Tk older than 8.4 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000057#endif
58
Serhiy Storchaka3af7a382015-04-22 10:53:08 +030059#if TK_HEX_VERSION >= 0x08050208 && TK_HEX_VERSION < 0x08060000 || \
60 TK_HEX_VERSION >= 0x08060200
Serhiy Storchakaea134da2015-04-02 18:46:50 +030061#define HAVE_LIBTOMMAMTH
62#include <tclTomMath.h>
63#endif
64
Jack Janseneddc1442003-11-20 01:44:59 +000065#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
Guido van Rossum0d2390c1997-08-14 19:57:07 +000066#define HAVE_CREATEFILEHANDLER
67#endif
68
Guido van Rossum00d93061998-05-28 23:06:38 +000069#ifdef HAVE_CREATEFILEHANDLER
70
Neal Norwitzd948a432006-01-08 01:08:55 +000071/* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere
72 with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */
73#ifndef TCL_UNIX_FD
74# ifdef TCL_WIN_SOCKET
75# define TCL_UNIX_FD (! TCL_WIN_SOCKET)
76# else
77# define TCL_UNIX_FD 1
78# endif
79#endif
80
Guido van Rossum00d93061998-05-28 23:06:38 +000081/* Tcl_CreateFileHandler() changed several times; these macros deal with the
82 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
83 Unix, only because Jack added it back); when available on Windows, it only
84 applies to sockets. */
85
Guido van Rossum7bf15641998-05-22 18:28:17 +000086#ifdef MS_WINDOWS
87#define FHANDLETYPE TCL_WIN_SOCKET
88#else
89#define FHANDLETYPE TCL_UNIX_FD
90#endif
91
Guido van Rossum00d93061998-05-28 23:06:38 +000092/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
93 which uses this to handle Tcl events while the user is typing commands. */
94
95#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +000096#define WAIT_FOR_STDIN
97#endif
98
Guido van Rossum00d93061998-05-28 23:06:38 +000099#endif /* HAVE_CREATEFILEHANDLER */
100
Guido van Rossumad4db171998-06-13 13:56:28 +0000101#ifdef MS_WINDOWS
102#include <conio.h>
103#define WAIT_FOR_STDIN
Zachary Ware7dc9dea2015-05-22 11:36:53 -0500104
105static PyObject *
106_get_tcl_lib_path()
107{
108 static PyObject *tcl_library_path = NULL;
109 static int already_checked = 0;
110
111 if (already_checked == 0) {
112 PyObject *prefix;
113 struct stat stat_buf;
114 int stat_return_value;
115
116 prefix = PyUnicode_FromWideChar(Py_GetPrefix(), -1);
117 if (prefix == NULL) {
118 return NULL;
119 }
120
121 /* Check expected location for an installed Python first */
122 tcl_library_path = PyUnicode_FromString("\\tcl\\tcl" TCL_VERSION);
123 if (tcl_library_path == NULL) {
124 return NULL;
125 }
126 tcl_library_path = PyUnicode_Concat(prefix, tcl_library_path);
127 if (tcl_library_path == NULL) {
128 return NULL;
129 }
130 stat_return_value = _Py_stat(tcl_library_path, &stat_buf);
131 if (stat_return_value == -2) {
132 return NULL;
133 }
134 if (stat_return_value == -1) {
135 /* install location doesn't exist, reset errno and see if
136 we're a repository build */
137 errno = 0;
138#ifdef Py_TCLTK_DIR
139 tcl_library_path = PyUnicode_FromString(
140 Py_TCLTK_DIR "\\lib\\tcl" TCL_VERSION);
141 if (tcl_library_path == NULL) {
142 return NULL;
143 }
144 stat_return_value = _Py_stat(tcl_library_path, &stat_buf);
145 if (stat_return_value == -2) {
146 return NULL;
147 }
148 if (stat_return_value == -1) {
149 /* tcltkDir for a repository build doesn't exist either,
150 reset errno and leave Tcl to its own devices */
151 errno = 0;
152 tcl_library_path = NULL;
153 }
154#else
155 tcl_library_path = NULL;
Guido van Rossumad4db171998-06-13 13:56:28 +0000156#endif
Zachary Ware7dc9dea2015-05-22 11:36:53 -0500157 }
158 already_checked = 1;
159 }
160 return tcl_library_path;
161}
162#endif /* MS_WINDOWS */
Guido van Rossumad4db171998-06-13 13:56:28 +0000163
Guido van Rossum00d93061998-05-28 23:06:38 +0000164#ifdef WITH_THREAD
165
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000166/* The threading situation is complicated. Tcl is not thread-safe, except
167 when configured with --enable-threads.
Guido van Rossum00d93061998-05-28 23:06:38 +0000168
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300169 So we need to use a lock around all uses of Tcl. Previously, the
170 Python interpreter lock was used for this. However, this causes
171 problems when other Python threads need to run while Tcl is blocked
172 waiting for events.
Guido van Rossum00d93061998-05-28 23:06:38 +0000173
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300174 To solve this problem, a separate lock for Tcl is introduced.
175 Holding it is incompatible with holding Python's interpreter lock.
176 The following four macros manipulate both locks together.
Guido van Rossum00d93061998-05-28 23:06:38 +0000177
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300178 ENTER_TCL and LEAVE_TCL are brackets, just like
179 Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS. They should be
180 used whenever a call into Tcl is made that could call an event
181 handler, or otherwise affect the state of a Tcl interpreter. These
182 assume that the surrounding code has the Python interpreter lock;
183 inside the brackets, the Python interpreter lock has been released
184 and the lock for Tcl has been acquired.
185
186 Sometimes, it is necessary to have both the Python lock and the Tcl
187 lock. (For example, when transferring data from the Tcl
188 interpreter result to a Python string object.) This can be done by
189 using different macros to close the ENTER_TCL block: ENTER_OVERLAP
190 reacquires the Python lock (and restores the thread state) but
191 doesn't release the Tcl lock; LEAVE_OVERLAP_TCL releases the Tcl
192 lock.
Guido van Rossum5e977831998-06-15 14:03:52 +0000193
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000194 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300195 handlers when the handler needs to use Python. Such event handlers
196 are entered while the lock for Tcl is held; the event handler
197 presumably needs to use Python. ENTER_PYTHON releases the lock for
198 Tcl and acquires the Python interpreter lock, restoring the
199 appropriate thread state, and LEAVE_PYTHON releases the Python
200 interpreter lock and re-acquires the lock for Tcl. It is okay for
201 ENTER_TCL/LEAVE_TCL pairs to be contained inside the code between
202 ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000203
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300204 These locks expand to several statements and brackets; they should
205 not be used in branches of if statements and the like.
Guido van Rossum00d93061998-05-28 23:06:38 +0000206
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300207 If Tcl is threaded, this approach won't work anymore. The Tcl
208 interpreter is only valid in the thread that created it, and all Tk
209 activity must happen in this thread, also. That means that the
210 mainloop must be invoked in the thread that created the
211 interpreter. Invoking commands from other threads is possible;
212 _tkinter will queue an event for the interpreter thread, which will
213 then execute the command and pass back the result. If the main
214 thread is not in the mainloop, and invoking commands causes an
215 exception; if the main loop is running but not processing events,
216 the command invocation will block.
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000217
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300218 In addition, for a threaded Tcl, a single global tcl_tstate won't
219 be sufficient anymore, since multiple Tcl interpreters may
220 simultaneously dispatch in different threads. So we use the Tcl TLS
221 API.
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000222
Guido van Rossum00d93061998-05-28 23:06:38 +0000223*/
224
Guido van Rossum65d5b571998-12-21 19:32:43 +0000225static PyThread_type_lock tcl_lock = 0;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000226
227#ifdef TCL_THREADS
228static Tcl_ThreadDataKey state_key;
229typedef PyThreadState *ThreadSpecificData;
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300230#define tcl_tstate \
231 (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*)))
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000232#else
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000233static PyThreadState *tcl_tstate = NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000234#endif
Guido van Rossum00d93061998-05-28 23:06:38 +0000235
236#define ENTER_TCL \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
238 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000239
240#define LEAVE_TCL \
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300241 tcl_tstate = NULL; \
242 if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000243
Guido van Rossum62320c91998-06-15 04:36:09 +0000244#define ENTER_OVERLAP \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 Py_END_ALLOW_THREADS
Guido van Rossum62320c91998-06-15 04:36:09 +0000246
247#define LEAVE_OVERLAP_TCL \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000249
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000250#define ENTER_PYTHON \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300252 if(tcl_lock) \
253 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000254
255#define LEAVE_PYTHON \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 { PyThreadState *tstate = PyEval_SaveThread(); \
257 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000258
259#define CHECK_TCL_APPARTMENT \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 if (((TkappObject *)self)->threaded && \
261 ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300262 PyErr_SetString(PyExc_RuntimeError, \
263 "Calling Tcl from different appartment"); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 return 0; \
265 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000266
267#else
268
269#define ENTER_TCL
270#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000271#define ENTER_OVERLAP
272#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000273#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000274#define LEAVE_PYTHON
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000275#define CHECK_TCL_APPARTMENT
Guido van Rossum00d93061998-05-28 23:06:38 +0000276
277#endif
278
Guido van Rossum97867b21996-08-08 19:09:53 +0000279#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000280#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000281#endif
282
Guido van Rossum18468821994-06-20 07:49:28 +0000283/**** Tkapp Object Declaration ****/
284
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300285static PyObject *Tkapp_Type;
Guido van Rossum18468821994-06-20 07:49:28 +0000286
Guido van Rossum00d93061998-05-28 23:06:38 +0000287typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 PyObject_HEAD
289 Tcl_Interp *interp;
290 int wantobjects;
291 int threaded; /* True if tcl_platform[threaded] */
292 Tcl_ThreadId thread_id;
293 int dispatching;
294 /* We cannot include tclInt.h, as this is internal.
295 So we cache interesting types here. */
Serhiy Storchakaf07a4b62015-03-23 00:47:45 +0200296 const Tcl_ObjType *OldBooleanType;
Zachary Ware037605b2014-08-05 11:54:34 -0500297 const Tcl_ObjType *BooleanType;
298 const Tcl_ObjType *ByteArrayType;
299 const Tcl_ObjType *DoubleType;
300 const Tcl_ObjType *IntType;
Serhiy Storchakaea134da2015-04-02 18:46:50 +0300301 const Tcl_ObjType *WideIntType;
302 const Tcl_ObjType *BignumType;
Zachary Ware037605b2014-08-05 11:54:34 -0500303 const Tcl_ObjType *ListType;
304 const Tcl_ObjType *ProcBodyType;
305 const Tcl_ObjType *StringType;
Guido van Rossum00d93061998-05-28 23:06:38 +0000306} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000307
Guido van Rossum18468821994-06-20 07:49:28 +0000308#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000309#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000310
Guido van Rossum35d43371997-08-02 00:09:09 +0000311#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Christian Heimes90aa7642007-12-19 02:45:37 +0000312(void *) v, Py_REFCNT(v)))
Guido van Rossum18468821994-06-20 07:49:28 +0000313
Barry Warsawfa701a81997-01-16 00:15:11 +0000314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315
Guido van Rossum18468821994-06-20 07:49:28 +0000316/**** Error Handling ****/
317
318static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000319static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000320static int errorInCmd = 0;
321static PyObject *excInCmd;
322static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000323static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000324
Guilherme Polob681df42009-02-09 22:33:59 +0000325#ifdef TKINTER_PROTECT_LOADTK
Alexandre Vassalotti21455952009-04-05 01:30:02 +0000326static int tk_load_failed = 0;
Guilherme Polob681df42009-02-09 22:33:59 +0000327#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329
Guido van Rossum18468821994-06-20 07:49:28 +0000330static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000331Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000332{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000333 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
334 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000335}
336
Barry Warsawfa701a81997-01-16 00:15:11 +0000337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338
Guido van Rossum18468821994-06-20 07:49:28 +0000339/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000340
Martin v. Löwis28e9ce92003-05-09 08:19:48 +0000341static int Tkinter_busywaitinterval = 20;
342
Guido van Rossum00d93061998-05-28 23:06:38 +0000343#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000344#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000345
Guido van Rossum00d93061998-05-28 23:06:38 +0000346/* Millisecond sleep() for Unix platforms. */
347
348static void
Fred Drake509d79a2000-07-08 04:04:38 +0000349Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 /* XXX Too bad if you don't have select(). */
352 struct timeval t;
353 t.tv_sec = milli/1000;
354 t.tv_usec = (milli%1000) * 1000;
355 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
Guido van Rossum00d93061998-05-28 23:06:38 +0000356}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000357#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000358
Martin v. Löwis5b26abb2002-12-28 09:23:09 +0000359/* Wait up to 1s for the mainloop to come up. */
360
361static int
362WaitForMainloop(TkappObject* self)
363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 int i;
365 for (i = 0; i < 10; i++) {
366 if (self->dispatching)
367 return 1;
368 Py_BEGIN_ALLOW_THREADS
369 Sleep(100);
370 Py_END_ALLOW_THREADS
371 }
372 if (self->dispatching)
373 return 1;
374 PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
375 return 0;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +0000376}
Martin v. Löwisa9656492003-03-30 08:44:58 +0000377#endif /* WITH_THREAD */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380
Guido van Rossum18468821994-06-20 07:49:28 +0000381#define ARGSZ 64
382
Barry Warsawfa701a81997-01-16 00:15:11 +0000383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384
Guido van Rossum18468821994-06-20 07:49:28 +0000385static PyObject *
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200386unicodeFromTclStringAndSize(const char *s, Py_ssize_t size)
387{
388 PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL);
389 if (!r && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
390 /* Tcl encodes null character as \xc0\x80 */
391 if (memchr(s, '\xc0', size)) {
392 char *buf, *q;
393 const char *e = s + size;
394 PyErr_Clear();
395 q = buf = (char *)PyMem_Malloc(size);
Serhiy Storchakab1ebfdd2014-07-14 12:20:15 +0300396 if (buf == NULL) {
397 PyErr_NoMemory();
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200398 return NULL;
Serhiy Storchakab1ebfdd2014-07-14 12:20:15 +0300399 }
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200400 while (s != e) {
401 if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') {
402 *q++ = '\0';
403 s += 2;
404 }
405 else
406 *q++ = *s++;
407 }
408 s = buf;
409 size = q - s;
410 r = PyUnicode_DecodeUTF8(s, size, NULL);
411 PyMem_Free(buf);
412 }
413 }
414 return r;
415}
416
417static PyObject *
418unicodeFromTclString(const char *s)
419{
420 return unicodeFromTclStringAndSize(s, strlen(s));
421}
422
423static PyObject *
424unicodeFromTclObj(Tcl_Obj *value)
425{
426 int len;
427 char *s = Tcl_GetStringFromObj(value, &len);
428 return unicodeFromTclStringAndSize(s, len);
429}
430
431
432static PyObject *
Serhiy Storchaka6716d602014-07-30 19:19:21 +0300433Split(const char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 int argc;
Serhiy Storchaka6716d602014-07-30 19:19:21 +0300436 const char **argv;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 if (list == NULL) {
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +0300440 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 }
Guido van Rossum18468821994-06-20 07:49:28 +0000442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
444 /* Not a list.
445 * Could be a quoted string containing funnies, e.g. {"}.
446 * Return the string itself.
447 */
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200448 return unicodeFromTclString(list);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 }
Guido van Rossum18468821994-06-20 07:49:28 +0000450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 if (argc == 0)
452 v = PyUnicode_FromString("");
453 else if (argc == 1)
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200454 v = unicodeFromTclString(argv[0]);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 else if ((v = PyTuple_New(argc)) != NULL) {
456 int i;
457 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 for (i = 0; i < argc; i++) {
460 if ((w = Split(argv[i])) == NULL) {
461 Py_DECREF(v);
462 v = NULL;
463 break;
464 }
Serhiy Storchaka696c8af2016-06-19 11:22:47 +0300465 PyTuple_SET_ITEM(v, i, w);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 }
467 }
468 Tcl_Free(FREECAST argv);
469 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000470}
471
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300472/* In some cases, Tcl will still return strings that are supposed to
473 be lists. SplitObj walks through a nested tuple, finding string
474 objects that need to be split. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000475
Martin v. Löwis59683e82008-06-13 07:50:45 +0000476static PyObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000477SplitObj(PyObject *arg)
478{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 if (PyTuple_Check(arg)) {
Serhiy Storchaka26861b02015-02-16 20:52:17 +0200480 Py_ssize_t i, size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 PyObject *elem, *newelem, *result;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000482
Serhiy Storchaka696c8af2016-06-19 11:22:47 +0300483 size = PyTuple_GET_SIZE(arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 result = NULL;
485 /* Recursively invoke SplitObj for all tuple items.
486 If this does not return a new object, no action is
487 needed. */
488 for(i = 0; i < size; i++) {
Serhiy Storchaka696c8af2016-06-19 11:22:47 +0300489 elem = PyTuple_GET_ITEM(arg, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 newelem = SplitObj(elem);
491 if (!newelem) {
492 Py_XDECREF(result);
493 return NULL;
494 }
495 if (!result) {
Serhiy Storchaka26861b02015-02-16 20:52:17 +0200496 Py_ssize_t k;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 if (newelem == elem) {
498 Py_DECREF(newelem);
499 continue;
500 }
501 result = PyTuple_New(size);
502 if (!result)
503 return NULL;
504 for(k = 0; k < i; k++) {
Serhiy Storchaka696c8af2016-06-19 11:22:47 +0300505 elem = PyTuple_GET_ITEM(arg, k);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 Py_INCREF(elem);
Serhiy Storchaka696c8af2016-06-19 11:22:47 +0300507 PyTuple_SET_ITEM(result, k, elem);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 }
509 }
Serhiy Storchaka696c8af2016-06-19 11:22:47 +0300510 PyTuple_SET_ITEM(result, i, newelem);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 }
512 if (result)
513 return result;
514 /* Fall through, returning arg. */
515 }
Serhiy Storchaka2b00c492014-05-21 17:12:21 +0300516 else if (PyList_Check(arg)) {
Serhiy Storchaka26861b02015-02-16 20:52:17 +0200517 Py_ssize_t i, size;
Serhiy Storchaka2b00c492014-05-21 17:12:21 +0300518 PyObject *elem, *newelem, *result;
519
520 size = PyList_GET_SIZE(arg);
521 result = PyTuple_New(size);
522 if (!result)
523 return NULL;
524 /* Recursively invoke SplitObj for all list items. */
525 for(i = 0; i < size; i++) {
526 elem = PyList_GET_ITEM(arg, i);
527 newelem = SplitObj(elem);
528 if (!newelem) {
529 Py_XDECREF(result);
530 return NULL;
531 }
Serhiy Storchaka696c8af2016-06-19 11:22:47 +0300532 PyTuple_SET_ITEM(result, i, newelem);
Serhiy Storchaka2b00c492014-05-21 17:12:21 +0300533 }
534 return result;
535 }
Serhiy Storchaka275d5fd2013-07-11 20:34:47 +0300536 else if (PyUnicode_Check(arg)) {
537 int argc;
Serhiy Storchaka6716d602014-07-30 19:19:21 +0300538 const char **argv;
Serhiy Storchaka275d5fd2013-07-11 20:34:47 +0300539 char *list = PyUnicode_AsUTF8(arg);
540
541 if (list == NULL ||
542 Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
543 Py_INCREF(arg);
544 return arg;
545 }
546 Tcl_Free(FREECAST argv);
547 if (argc > 1)
548 return Split(list);
549 /* Fall through, returning arg. */
550 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 else if (PyBytes_Check(arg)) {
552 int argc;
Serhiy Storchaka6716d602014-07-30 19:19:21 +0300553 const char **argv;
Serhiy Storchaka696c8af2016-06-19 11:22:47 +0300554 char *list = PyBytes_AS_STRING(arg);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
557 Py_INCREF(arg);
558 return arg;
559 }
560 Tcl_Free(FREECAST argv);
561 if (argc > 1)
Serhiy Storchaka696c8af2016-06-19 11:22:47 +0300562 return Split(PyBytes_AS_STRING(arg));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 /* Fall through, returning arg. */
564 }
565 Py_INCREF(arg);
566 return arg;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000567}
Barry Warsawfa701a81997-01-16 00:15:11 +0000568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +0300570/*[clinic input]
571module _tkinter
572class _tkinter.tkapp "TkappObject *" "&Tkapp_Type_spec"
573class _tkinter.Tcl_Obj "PyTclObject *" "&PyTclObject_Type_spec"
574class _tkinter.tktimertoken "TkttObject *" "&Tktt_Type_spec"
575[clinic start generated code]*/
576/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b1ebf15c162ee229]*/
577
Guido van Rossum18468821994-06-20 07:49:28 +0000578/**** Tkapp Object ****/
579
580#ifndef WITH_APPINIT
581int
Fred Drake509d79a2000-07-08 04:04:38 +0000582Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000583{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 const char * _tkinter_skip_tk_init;
Guido van Rossumec22c921996-02-25 04:50:29 +0000585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 if (Tcl_Init(interp) == TCL_ERROR) {
587 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
588 return TCL_ERROR;
589 }
Guilherme Polob681df42009-02-09 22:33:59 +0000590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 _tkinter_skip_tk_init = Tcl_GetVar(interp,
592 "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
593 if (_tkinter_skip_tk_init != NULL &&
594 strcmp(_tkinter_skip_tk_init, "1") == 0) {
595 return TCL_OK;
596 }
Guilherme Polob681df42009-02-09 22:33:59 +0000597
598#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 if (tk_load_failed) {
600 PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG);
601 return TCL_ERROR;
602 }
Guilherme Polob681df42009-02-09 22:33:59 +0000603#endif
604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 if (Tk_Init(interp) == TCL_ERROR) {
Guilherme Polob681df42009-02-09 22:33:59 +0000606#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 tk_load_failed = 1;
Guilherme Polob681df42009-02-09 22:33:59 +0000608#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
610 return TCL_ERROR;
611 }
Guilherme Polob681df42009-02-09 22:33:59 +0000612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000614}
615#endif /* !WITH_APPINIT */
616
Guido van Rossum18468821994-06-20 07:49:28 +0000617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618
Barry Warsawfa701a81997-01-16 00:15:11 +0000619
620/* Initialize the Tk application; see the `main' function in
621 * `tkMain.c'.
622 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000623
Thomas Wouters58d05102000-07-24 14:43:35 +0000624static void EnableEventHook(void); /* Forward */
625static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000626
Barry Warsawfa701a81997-01-16 00:15:11 +0000627static TkappObject *
Serhiy Storchaka6716d602014-07-30 19:19:21 +0300628Tkapp_New(const char *screenName, const char *className,
629 int interactive, int wantobjects, int wantTk, int sync,
630 const char *use)
Barry Warsawfa701a81997-01-16 00:15:11 +0000631{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 TkappObject *v;
633 char *argv0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000634
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300635 v = PyObject_New(TkappObject, (PyTypeObject *) Tkapp_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 if (v == NULL)
637 return NULL;
Antoine Pitrou584e8152013-08-11 00:22:30 +0200638 Py_INCREF(Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 v->interp = Tcl_CreateInterp();
641 v->wantobjects = wantobjects;
642 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
643 TCL_GLOBAL_ONLY) != NULL;
644 v->thread_id = Tcl_GetCurrentThread();
645 v->dispatching = 0;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000646
647#ifndef TCL_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 if (v->threaded) {
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +0300649 PyErr_SetString(PyExc_RuntimeError,
650 "Tcl is threaded but _tkinter is not");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 Py_DECREF(v);
652 return 0;
653 }
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000654#endif
Martin v. Löwisa9656492003-03-30 08:44:58 +0000655#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 if (v->threaded && tcl_lock) {
657 /* If Tcl is threaded, we don't need the lock. */
658 PyThread_free_lock(tcl_lock);
659 tcl_lock = NULL;
660 }
Martin v. Löwisa9656492003-03-30 08:44:58 +0000661#endif
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000662
Serhiy Storchakaf07a4b62015-03-23 00:47:45 +0200663 v->OldBooleanType = Tcl_GetObjType("boolean");
664 v->BooleanType = Tcl_GetObjType("booleanString");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 v->ByteArrayType = Tcl_GetObjType("bytearray");
666 v->DoubleType = Tcl_GetObjType("double");
667 v->IntType = Tcl_GetObjType("int");
Serhiy Storchakaea134da2015-04-02 18:46:50 +0300668 v->WideIntType = Tcl_GetObjType("wideInt");
669 v->BignumType = Tcl_GetObjType("bignum");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 v->ListType = Tcl_GetObjType("list");
671 v->ProcBodyType = Tcl_GetObjType("procbody");
672 v->StringType = Tcl_GetObjType("string");
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 /* Delete the 'exit' command, which can screw things up */
675 Tcl_DeleteCommand(v->interp, "exit");
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 if (screenName != NULL)
678 Tcl_SetVar2(v->interp, "env", "DISPLAY",
679 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 if (interactive)
682 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
683 else
684 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000686 /* This is used to get the application class for Tk 4.1 and up */
Victor Stinneree6c3c72014-09-11 17:50:21 +0200687 argv0 = (char*)PyMem_Malloc(strlen(className) + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 if (!argv0) {
689 PyErr_NoMemory();
690 Py_DECREF(v);
691 return NULL;
692 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 strcpy(argv0, className);
Antoine Pitroued8ba142011-10-04 13:50:21 +0200695 if (Py_ISUPPER(Py_CHARMASK(argv0[0])))
696 argv0[0] = Py_TOLOWER(Py_CHARMASK(argv0[0]));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
Victor Stinneree6c3c72014-09-11 17:50:21 +0200698 PyMem_Free(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 if (! wantTk) {
701 Tcl_SetVar(v->interp,
702 "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
703 }
Guilherme Polob681df42009-02-09 22:33:59 +0000704#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 else if (tk_load_failed) {
706 Tcl_SetVar(v->interp,
707 "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY);
708 }
Guilherme Polob681df42009-02-09 22:33:59 +0000709#endif
David Aschere2b4b322004-02-18 05:59:53 +0000710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 /* some initial arguments need to be in argv */
712 if (sync || use) {
713 char *args;
Serhiy Storchaka26861b02015-02-16 20:52:17 +0200714 Py_ssize_t len = 0;
Tim Peters51fa3b72004-08-04 02:16:48 +0000715
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 if (sync)
717 len += sizeof "-sync";
718 if (use)
Serhiy Storchaka26861b02015-02-16 20:52:17 +0200719 len += strlen(use) + sizeof "-use "; /* never overflows */
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000720
Victor Stinneree6c3c72014-09-11 17:50:21 +0200721 args = (char*)PyMem_Malloc(len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 if (!args) {
723 PyErr_NoMemory();
724 Py_DECREF(v);
725 return NULL;
726 }
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 args[0] = '\0';
729 if (sync)
730 strcat(args, "-sync");
731 if (use) {
732 if (sync)
733 strcat(args, " ");
734 strcat(args, "-use ");
735 strcat(args, use);
736 }
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
Victor Stinneree6c3c72014-09-11 17:50:21 +0200739 PyMem_Free(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 }
Martin v. Löwis1fa649f2004-08-03 18:45:31 +0000741
Zachary Ware7dc9dea2015-05-22 11:36:53 -0500742#ifdef MS_WINDOWS
743 {
744 PyObject *str_path;
745 PyObject *utf8_path;
746 DWORD ret;
747
748 ret = GetEnvironmentVariableW(L"TCL_LIBRARY", NULL, 0);
749 if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
750 str_path = _get_tcl_lib_path();
751 if (str_path == NULL && PyErr_Occurred()) {
752 return NULL;
753 }
754 if (str_path != NULL) {
755 utf8_path = PyUnicode_AsUTF8String(str_path);
756 if (utf8_path == NULL) {
757 return NULL;
758 }
759 Tcl_SetVar(v->interp,
760 "tcl_library",
Serhiy Storchaka696c8af2016-06-19 11:22:47 +0300761 PyBytes_AS_STRING(utf8_path),
Zachary Ware7dc9dea2015-05-22 11:36:53 -0500762 TCL_GLOBAL_ONLY);
763 Py_DECREF(utf8_path);
764 }
765 }
766 }
767#endif
768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 if (Tcl_AppInit(v->interp) != TCL_OK) {
770 PyObject *result = Tkinter_Error((PyObject *)v);
Guilherme Polob681df42009-02-09 22:33:59 +0000771#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772 if (wantTk) {
773 const char *_tkinter_tk_failed;
774 _tkinter_tk_failed = Tcl_GetVar(v->interp,
775 "_tkinter_tk_failed", TCL_GLOBAL_ONLY);
Guilherme Polob681df42009-02-09 22:33:59 +0000776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000777 if ( _tkinter_tk_failed != NULL &&
778 strcmp(_tkinter_tk_failed, "1") == 0) {
779 tk_load_failed = 1;
780 }
781 }
Guilherme Polob681df42009-02-09 22:33:59 +0000782#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 Py_DECREF((PyObject *)v);
784 return (TkappObject *)result;
785 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 EnableEventHook();
Guido van Rossum7bf15641998-05-22 18:28:17 +0000788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000790}
791
Barry Warsawfa701a81997-01-16 00:15:11 +0000792
Benjamin Peterson5879d412009-03-30 14:51:56 +0000793#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000794static void
795Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 Tcl_Condition *cond, Tcl_Mutex *mutex)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 Py_BEGIN_ALLOW_THREADS;
799 Tcl_MutexLock(mutex);
800 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
801 Tcl_ThreadAlert(self->thread_id);
802 Tcl_ConditionWait(cond, mutex, NULL);
803 Tcl_MutexUnlock(mutex);
804 Py_END_ALLOW_THREADS
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000805}
Benjamin Peterson5879d412009-03-30 14:51:56 +0000806#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +0000807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808
Guido van Rossum18468821994-06-20 07:49:28 +0000809/** Tcl Eval **/
810
Martin v. Löwisffad6332002-11-26 09:28:05 +0000811typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000812 PyObject_HEAD
813 Tcl_Obj *value;
814 PyObject *string; /* This cannot cause cycles. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000815} PyTclObject;
816
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300817static PyObject *PyTclObject_Type;
818#define PyTclObject_Check(v) ((v)->ob_type == (PyTypeObject *) PyTclObject_Type)
Martin v. Löwisffad6332002-11-26 09:28:05 +0000819
820static PyObject *
821newPyTclObject(Tcl_Obj *arg)
822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823 PyTclObject *self;
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300824 self = PyObject_New(PyTclObject, (PyTypeObject *) PyTclObject_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000825 if (self == NULL)
826 return NULL;
Antoine Pitrou584e8152013-08-11 00:22:30 +0200827 Py_INCREF(PyTclObject_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000828 Tcl_IncrRefCount(arg);
829 self->value = arg;
830 self->string = NULL;
831 return (PyObject*)self;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000832}
833
834static void
835PyTclObject_dealloc(PyTclObject *self)
836{
Antoine Pitrou584e8152013-08-11 00:22:30 +0200837 PyObject *tp = (PyObject *) Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 Tcl_DecrRefCount(self->value);
839 Py_XDECREF(self->string);
840 PyObject_Del(self);
Antoine Pitrou584e8152013-08-11 00:22:30 +0200841 Py_DECREF(tp);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000842}
843
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200844static const char *
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000845PyTclObject_TclString(PyObject *self)
846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 return Tcl_GetString(((PyTclObject*)self)->value);
Martin v. Löwis1869ec52003-05-01 05:47:00 +0000848}
849
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000850/* Like _str, but create Unicode if necessary. */
Guido van Rossum82c0dfa2007-11-21 20:09:18 +0000851PyDoc_STRVAR(PyTclObject_string__doc__,
Christian Heimesb2b62622007-11-22 05:56:35 +0000852"the string representation of this object, either as str or bytes");
Martin v. Löwis39195712003-01-04 00:33:13 +0000853
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000854static PyObject *
855PyTclObject_string(PyTclObject *self, void *ignored)
856{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 if (!self->string) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200858 self->string = unicodeFromTclObj(self->value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 if (!self->string)
860 return NULL;
861 }
862 Py_INCREF(self->string);
863 return self->string;
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000864}
865
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000866static PyObject *
Walter Dörwald6720d912007-07-12 12:12:25 +0000867PyTclObject_str(PyTclObject *self, void *ignored)
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000868{
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200869 if (self->string) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 Py_INCREF(self->string);
871 return self->string;
872 }
873 /* XXX Could chache result if it is non-ASCII. */
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200874 return unicodeFromTclObj(self->value);
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000875}
Martin v. Löwis25c7b502003-01-04 00:08:09 +0000876
Martin v. Löwisffad6332002-11-26 09:28:05 +0000877static PyObject *
878PyTclObject_repr(PyTclObject *self)
879{
Serhiy Storchaka463bd4b2013-09-23 22:49:02 +0300880 PyObject *repr, *str = PyTclObject_str(self, NULL);
881 if (str == NULL)
882 return NULL;
883 repr = PyUnicode_FromFormat("<%s object: %R>",
884 self->value->typePtr->name, str);
885 Py_DECREF(str);
886 return repr;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000887}
888
Mark Dickinson211c6252009-02-01 10:28:51 +0000889#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
890
891static PyObject *
892PyTclObject_richcompare(PyObject *self, PyObject *other, int op)
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000893{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 int result;
895 PyObject *v;
Mark Dickinson211c6252009-02-01 10:28:51 +0000896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000897 /* neither argument should be NULL, unless something's gone wrong */
898 if (self == NULL || other == NULL) {
899 PyErr_BadInternalCall();
900 return NULL;
901 }
Mark Dickinson211c6252009-02-01 10:28:51 +0000902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 /* both arguments should be instances of PyTclObject */
904 if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) {
905 v = Py_NotImplemented;
906 goto finished;
907 }
Mark Dickinson211c6252009-02-01 10:28:51 +0000908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 if (self == other)
910 /* fast path when self and other are identical */
911 result = 0;
912 else
913 result = strcmp(Tcl_GetString(((PyTclObject *)self)->value),
914 Tcl_GetString(((PyTclObject *)other)->value));
915 /* Convert return value to a Boolean */
916 switch (op) {
917 case Py_EQ:
918 v = TEST_COND(result == 0);
919 break;
920 case Py_NE:
921 v = TEST_COND(result != 0);
922 break;
923 case Py_LE:
924 v = TEST_COND(result <= 0);
925 break;
926 case Py_GE:
927 v = TEST_COND(result >= 0);
928 break;
929 case Py_LT:
930 v = TEST_COND(result < 0);
931 break;
932 case Py_GT:
933 v = TEST_COND(result > 0);
934 break;
935 default:
936 PyErr_BadArgument();
937 return NULL;
938 }
Mark Dickinson211c6252009-02-01 10:28:51 +0000939 finished:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 Py_INCREF(v);
941 return v;
Martin v. Löwisdd6cd652003-05-03 09:45:12 +0000942}
943
Martin v. Löwis39195712003-01-04 00:33:13 +0000944PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
945
Martin v. Löwisffad6332002-11-26 09:28:05 +0000946static PyObject*
947get_typename(PyTclObject* obj, void* ignored)
948{
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200949 return unicodeFromTclString(obj->value->typePtr->name);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000950}
951
Martin v. Löwis39195712003-01-04 00:33:13 +0000952
Martin v. Löwisffad6332002-11-26 09:28:05 +0000953static PyGetSetDef PyTclObject_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 {"typename", (getter)get_typename, NULL, get_typename__doc__},
955 {"string", (getter)PyTclObject_string, NULL,
956 PyTclObject_string__doc__},
957 {0},
Martin v. Löwisffad6332002-11-26 09:28:05 +0000958};
959
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300960static PyType_Slot PyTclObject_Type_slots[] = {
961 {Py_tp_dealloc, (destructor)PyTclObject_dealloc},
962 {Py_tp_repr, (reprfunc)PyTclObject_repr},
963 {Py_tp_str, (reprfunc)PyTclObject_str},
Andrew Svetlovd2217a82012-10-30 22:49:16 +0200964 {Py_tp_getattro, PyObject_GenericGetAttr},
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300965 {Py_tp_richcompare, PyTclObject_richcompare},
966 {Py_tp_getset, PyTclObject_getsetlist},
967 {0, 0}
Martin v. Löwisffad6332002-11-26 09:28:05 +0000968};
969
Andrew Svetlov11dc6c32012-10-14 16:54:35 +0300970static PyType_Spec PyTclObject_Type_spec = {
971 "_tkinter.Tcl_Obj",
972 sizeof(PyTclObject),
973 0,
974 Py_TPFLAGS_DEFAULT,
975 PyTclObject_Type_slots,
976};
977
978
Benjamin Peterson2f8bfef2016-09-07 09:26:18 -0700979#if SIZE_MAX > INT_MAX
Serhiy Storchaka79851d72014-05-30 14:24:03 +0300980#define CHECK_STRING_LENGTH(s) do { \
981 if (s != NULL && strlen(s) >= INT_MAX) { \
982 PyErr_SetString(PyExc_OverflowError, "string is too long"); \
983 return NULL; \
984 } } while(0)
985#else
986#define CHECK_STRING_LENGTH(s)
987#endif
988
Serhiy Storchakaea134da2015-04-02 18:46:50 +0300989#ifdef HAVE_LIBTOMMAMTH
990static Tcl_Obj*
991asBignumObj(PyObject *value)
992{
993 Tcl_Obj *result;
994 int neg;
995 PyObject *hexstr;
996 char *hexchars;
997 mp_int bigValue;
998
999 neg = Py_SIZE(value) < 0;
1000 hexstr = _PyLong_Format(value, 16);
1001 if (hexstr == NULL)
1002 return NULL;
1003 hexchars = PyUnicode_AsUTF8(hexstr);
1004 if (hexchars == NULL) {
1005 Py_DECREF(hexstr);
1006 return NULL;
1007 }
1008 hexchars += neg + 2; /* skip sign and "0x" */
1009 mp_init(&bigValue);
1010 if (mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) {
1011 mp_clear(&bigValue);
1012 Py_DECREF(hexstr);
1013 PyErr_NoMemory();
1014 return NULL;
1015 }
1016 Py_DECREF(hexstr);
1017 bigValue.sign = neg ? MP_NEG : MP_ZPOS;
1018 result = Tcl_NewBignumObj(&bigValue);
1019 mp_clear(&bigValue);
1020 if (result == NULL) {
1021 PyErr_NoMemory();
1022 return NULL;
1023 }
1024 return result;
1025}
1026#endif
1027
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001028static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +00001029AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001030{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 Tcl_Obj *result;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001032
Serhiy Storchaka26861b02015-02-16 20:52:17 +02001033 if (PyBytes_Check(value)) {
1034 if (PyBytes_GET_SIZE(value) >= INT_MAX) {
1035 PyErr_SetString(PyExc_OverflowError, "bytes object is too long");
1036 return NULL;
1037 }
Serhiy Storchaka74596a82014-07-30 18:33:13 +03001038 return Tcl_NewByteArrayObj((unsigned char *)PyBytes_AS_STRING(value),
Serhiy Storchaka26861b02015-02-16 20:52:17 +02001039 (int)PyBytes_GET_SIZE(value));
1040 }
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001041
1042 if (PyBool_Check(value))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001044
1045 if (PyLong_CheckExact(value)) {
1046 int overflow;
1047 long longValue;
1048#ifdef TCL_WIDE_INT_TYPE
1049 Tcl_WideInt wideValue;
1050#endif
1051 longValue = PyLong_AsLongAndOverflow(value, &overflow);
1052 if (!overflow) {
1053 return Tcl_NewLongObj(longValue);
1054 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 /* If there is an overflow in the long conversion,
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001056 fall through to wideInt handling. */
1057#ifdef TCL_WIDE_INT_TYPE
1058 if (_PyLong_AsByteArray((PyLongObject *)value,
1059 (unsigned char *)(void *)&wideValue,
1060 sizeof(wideValue),
1061 PY_LITTLE_ENDIAN,
1062 /* signed */ 1) == 0) {
1063 return Tcl_NewWideIntObj(wideValue);
1064 }
1065 PyErr_Clear();
1066#endif
1067 /* If there is an overflow in the wideInt conversion,
1068 fall through to bignum handling. */
1069#ifdef HAVE_LIBTOMMAMTH
1070 return asBignumObj(value);
1071#endif
1072 /* If there is no wideInt or bignum support,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 fall through to default object handling. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 }
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001075
1076 if (PyFloat_Check(value))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001078
Serhiy Storchaka4c7dc482015-04-02 18:49:14 +03001079 if (PyTuple_Check(value) || PyList_Check(value)) {
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +03001080 Tcl_Obj **argv;
1081 Py_ssize_t size, i;
1082
Serhiy Storchaka2b00c492014-05-21 17:12:21 +03001083 size = PySequence_Fast_GET_SIZE(value);
Serhiy Storchakaabf68ce2014-09-11 10:57:13 +03001084 if (size == 0)
1085 return Tcl_NewListObj(0, NULL);
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +03001086 if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) {
Serhiy Storchaka2b00c492014-05-21 17:12:21 +03001087 PyErr_SetString(PyExc_OverflowError,
1088 PyTuple_Check(value) ? "tuple is too long" :
1089 "list is too long");
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +03001090 return NULL;
1091 }
Victor Stinneree6c3c72014-09-11 17:50:21 +02001092 argv = (Tcl_Obj **) PyMem_Malloc(((size_t)size) * sizeof(Tcl_Obj *));
1093 if (!argv) {
Victor Stinner60a64d62014-09-04 17:29:52 +02001094 PyErr_NoMemory();
1095 return NULL;
1096 }
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +03001097 for (i = 0; i < size; i++)
Serhiy Storchaka2b00c492014-05-21 17:12:21 +03001098 argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i));
Serhiy Storchaka26861b02015-02-16 20:52:17 +02001099 result = Tcl_NewListObj((int)size, argv);
Victor Stinneree6c3c72014-09-11 17:50:21 +02001100 PyMem_Free(argv);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 return result;
1102 }
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001103
1104 if (PyUnicode_Check(value)) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001105 void *inbuf;
1106 Py_ssize_t size;
1107 int kind;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 Tcl_UniChar *outbuf = NULL;
1109 Py_ssize_t i;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001110 size_t allocsize;
1111
1112 if (PyUnicode_READY(value) == -1)
1113 return NULL;
1114
1115 inbuf = PyUnicode_DATA(value);
1116 size = PyUnicode_GET_LENGTH(value);
Serhiy Storchakaabf68ce2014-09-11 10:57:13 +03001117 if (size == 0)
1118 return Tcl_NewUnicodeObj((const void *)"", 0);
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +03001119 if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) {
1120 PyErr_SetString(PyExc_OverflowError, "string is too long");
1121 return NULL;
1122 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001123 kind = PyUnicode_KIND(value);
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001124 if (kind == sizeof(Tcl_UniChar))
Serhiy Storchaka26861b02015-02-16 20:52:17 +02001125 return Tcl_NewUnicodeObj(inbuf, (int)size);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001126 allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
Victor Stinneree6c3c72014-09-11 17:50:21 +02001127 outbuf = (Tcl_UniChar*)PyMem_Malloc(allocsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 /* Else overflow occurred, and we take the next exit */
1129 if (!outbuf) {
1130 PyErr_NoMemory();
1131 return NULL;
1132 }
1133 for (i = 0; i < size; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001134 Py_UCS4 ch = PyUnicode_READ(kind, inbuf, i);
1135 /* We cannot test for sizeof(Tcl_UniChar) directly,
1136 so we test for UTF-8 size instead. */
1137#if TCL_UTF_MAX == 3
1138 if (ch >= 0x10000) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 /* Tcl doesn't do UTF-16, yet. */
Serhiy Storchaka59f5dee2013-02-18 13:01:52 +02001140 PyErr_Format(Tkinter_TclError,
Victor Stinner7ab41922011-11-04 00:36:46 +01001141 "character U+%x is above the range "
1142 "(U+0000-U+FFFF) allowed by Tcl",
Victor Stinner3d7acb02011-11-04 09:49:24 +01001143 ch);
Victor Stinneree6c3c72014-09-11 17:50:21 +02001144 PyMem_Free(outbuf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 return NULL;
1146 }
Andrew Svetlov80823d72012-07-22 13:56:54 +03001147#endif
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001148 outbuf[i] = ch;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 }
Serhiy Storchaka26861b02015-02-16 20:52:17 +02001150 result = Tcl_NewUnicodeObj(outbuf, (int)size);
Victor Stinneree6c3c72014-09-11 17:50:21 +02001151 PyMem_Free(outbuf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 return result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 }
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001154
1155 if (PyTclObject_Check(value)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 Tcl_Obj *v = ((PyTclObject*)value)->value;
1157 Tcl_IncrRefCount(v);
1158 return v;
1159 }
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001160
1161 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 PyObject *v = PyObject_Str(value);
1163 if (!v)
1164 return 0;
1165 result = AsObj(v);
1166 Py_DECREF(v);
1167 return result;
1168 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +00001169}
1170
Serhiy Storchakaf7de3dd2015-04-02 10:35:57 +03001171static PyObject *
1172fromBoolean(PyObject* tkapp, Tcl_Obj *value)
1173{
1174 int boolValue;
1175 if (Tcl_GetBooleanFromObj(Tkapp_Interp(tkapp), value, &boolValue) == TCL_ERROR)
1176 return Tkinter_Error(tkapp);
1177 return PyBool_FromLong(boolValue);
1178}
1179
Martin v. Löwisffad6332002-11-26 09:28:05 +00001180static PyObject*
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001181fromWideIntObj(PyObject* tkapp, Tcl_Obj *value)
1182{
1183 Tcl_WideInt wideValue;
1184 if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL_OK) {
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001185 if (sizeof(wideValue) <= SIZEOF_LONG_LONG)
1186 return PyLong_FromLongLong(wideValue);
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001187 return _PyLong_FromByteArray((unsigned char *)(void *)&wideValue,
1188 sizeof(wideValue),
1189 PY_LITTLE_ENDIAN,
1190 /* signed */ 1);
1191 }
1192 return NULL;
1193}
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001194
1195#ifdef HAVE_LIBTOMMAMTH
1196static PyObject*
1197fromBignumObj(PyObject* tkapp, Tcl_Obj *value)
1198{
1199 mp_int bigValue;
1200 unsigned long numBytes;
1201 unsigned char *bytes;
1202 PyObject *res;
1203
1204 if (Tcl_GetBignumFromObj(Tkapp_Interp(tkapp), value, &bigValue) != TCL_OK)
1205 return Tkinter_Error(tkapp);
1206 numBytes = mp_unsigned_bin_size(&bigValue);
1207 bytes = PyMem_Malloc(numBytes);
1208 if (bytes == NULL) {
1209 mp_clear(&bigValue);
1210 return PyErr_NoMemory();
1211 }
1212 if (mp_to_unsigned_bin_n(&bigValue, bytes,
1213 &numBytes) != MP_OKAY) {
1214 mp_clear(&bigValue);
1215 PyMem_Free(bytes);
1216 return PyErr_NoMemory();
1217 }
1218 res = _PyLong_FromByteArray(bytes, numBytes,
1219 /* big-endian */ 0,
1220 /* unsigned */ 0);
1221 PyMem_Free(bytes);
1222 if (res != NULL && bigValue.sign == MP_NEG) {
1223 PyObject *res2 = PyNumber_Negative(res);
1224 Py_DECREF(res);
1225 res = res2;
1226 }
1227 mp_clear(&bigValue);
1228 return res;
1229}
1230#endif
1231
Martin v. Löwisffad6332002-11-26 09:28:05 +00001232static PyObject*
1233FromObj(PyObject* tkapp, Tcl_Obj *value)
1234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 PyObject *result = NULL;
1236 TkappObject *app = (TkappObject*)tkapp;
Serhiy Storchakaf07a4b62015-03-23 00:47:45 +02001237 Tcl_Interp *interp = Tkapp_Interp(tkapp);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 if (value->typePtr == NULL) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001240 return unicodeFromTclStringAndSize(value->bytes, value->length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001242
Serhiy Storchakaf07a4b62015-03-23 00:47:45 +02001243 if (value->typePtr == app->BooleanType ||
1244 value->typePtr == app->OldBooleanType) {
Serhiy Storchakaf7de3dd2015-04-02 10:35:57 +03001245 return fromBoolean(tkapp, value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 if (value->typePtr == app->ByteArrayType) {
1249 int size;
1250 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
1251 return PyBytes_FromStringAndSize(data, size);
1252 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 if (value->typePtr == app->DoubleType) {
1255 return PyFloat_FromDouble(value->internalRep.doubleValue);
1256 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 if (value->typePtr == app->IntType) {
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001259 long longValue;
1260 if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK)
1261 return PyLong_FromLong(longValue);
1262 /* If there is an error in the long conversion,
1263 fall through to wideInt handling. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001265
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001266 if (value->typePtr == app->IntType ||
1267 value->typePtr == app->WideIntType) {
1268 result = fromWideIntObj(tkapp, value);
1269 if (result != NULL || PyErr_Occurred())
1270 return result;
1271 Tcl_ResetResult(interp);
1272 /* If there is an error in the wideInt conversion,
1273 fall through to bignum handling. */
1274 }
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001275
1276#ifdef HAVE_LIBTOMMAMTH
1277 if (value->typePtr == app->IntType ||
1278 value->typePtr == app->WideIntType ||
1279 value->typePtr == app->BignumType) {
1280 return fromBignumObj(tkapp, value);
1281 }
1282#endif
1283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 if (value->typePtr == app->ListType) {
1285 int size;
1286 int i, status;
1287 PyObject *elem;
1288 Tcl_Obj *tcl_elem;
Martin v. Löwisffad6332002-11-26 09:28:05 +00001289
Serhiy Storchakaf07a4b62015-03-23 00:47:45 +02001290 status = Tcl_ListObjLength(interp, value, &size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 if (status == TCL_ERROR)
1292 return Tkinter_Error(tkapp);
1293 result = PyTuple_New(size);
1294 if (!result)
1295 return NULL;
1296 for (i = 0; i < size; i++) {
Serhiy Storchakaf07a4b62015-03-23 00:47:45 +02001297 status = Tcl_ListObjIndex(interp, value, i, &tcl_elem);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 if (status == TCL_ERROR) {
1299 Py_DECREF(result);
1300 return Tkinter_Error(tkapp);
1301 }
1302 elem = FromObj(tkapp, tcl_elem);
1303 if (!elem) {
1304 Py_DECREF(result);
1305 return NULL;
1306 }
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03001307 PyTuple_SET_ITEM(result, i, elem);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 }
1309 return result;
1310 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 if (value->typePtr == app->ProcBodyType) {
1313 /* fall through: return tcl object. */
1314 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 if (value->typePtr == app->StringType) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001317 return PyUnicode_FromKindAndData(
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001318 sizeof(Tcl_UniChar), Tcl_GetUnicode(value),
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001319 Tcl_GetCharLength(value));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 }
Martin v. Löwisffad6332002-11-26 09:28:05 +00001321
Serhiy Storchaka3af7a382015-04-22 10:53:08 +03001322#if TK_HEX_VERSION >= 0x08050000
Serhiy Storchakaf7de3dd2015-04-02 10:35:57 +03001323 if (app->BooleanType == NULL &&
1324 strcmp(value->typePtr->name, "booleanString") == 0) {
1325 /* booleanString type is not registered in Tcl */
1326 app->BooleanType = value->typePtr;
1327 return fromBoolean(tkapp, value);
1328 }
1329#endif
1330
Serhiy Storchakaea134da2015-04-02 18:46:50 +03001331#ifdef HAVE_LIBTOMMAMTH
1332 if (app->BignumType == NULL &&
1333 strcmp(value->typePtr->name, "bignum") == 0) {
1334 /* bignum type is not registered in Tcl */
1335 app->BignumType = value->typePtr;
1336 return fromBignumObj(tkapp, value);
1337 }
1338#endif
1339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 return newPyTclObject(value);
Martin v. Löwisffad6332002-11-26 09:28:05 +00001341}
1342
Benjamin Peterson5879d412009-03-30 14:51:56 +00001343#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001344/* This mutex synchronizes inter-thread command calls. */
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001345TCL_DECLARE_MUTEX(call_mutex)
1346
1347typedef struct Tkapp_CallEvent {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 Tcl_Event ev; /* Must be first */
1349 TkappObject *self;
1350 PyObject *args;
1351 int flags;
1352 PyObject **res;
1353 PyObject **exc_type, **exc_value, **exc_tb;
1354 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001355} Tkapp_CallEvent;
Benjamin Peterson5879d412009-03-30 14:51:56 +00001356#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001357
1358void
1359Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
Guido van Rossum18468821994-06-20 07:49:28 +00001360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 int i;
1362 for (i = 0; i < objc; i++)
1363 Tcl_DecrRefCount(objv[i]);
1364 if (objv != objStore)
Victor Stinneree6c3c72014-09-11 17:50:21 +02001365 PyMem_Free(objv);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001366}
Guido van Rossum18468821994-06-20 07:49:28 +00001367
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001368/* Convert Python objects to Tcl objects. This must happen in the
1369 interpreter thread, which may or may not be the calling thread. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001370
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001371static Tcl_Obj**
1372Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 Tcl_Obj **objv = objStore;
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +03001375 Py_ssize_t objc = 0, i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 if (args == NULL)
1377 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +00001378
Serhiy Storchaka2b00c492014-05-21 17:12:21 +03001379 else if (!(PyTuple_Check(args) || PyList_Check(args))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 objv[0] = AsObj(args);
1381 if (objv[0] == 0)
1382 goto finally;
1383 objc = 1;
1384 Tcl_IncrRefCount(objv[0]);
1385 }
1386 else {
Serhiy Storchaka2b00c492014-05-21 17:12:21 +03001387 objc = PySequence_Fast_GET_SIZE(args);
Guido van Rossum212643f1998-04-29 16:22:14 +00001388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 if (objc > ARGSZ) {
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +03001390 if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) {
Serhiy Storchaka2b00c492014-05-21 17:12:21 +03001391 PyErr_SetString(PyExc_OverflowError,
1392 PyTuple_Check(args) ? "tuple is too long" :
1393 "list is too long");
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +03001394 return NULL;
1395 }
Victor Stinneree6c3c72014-09-11 17:50:21 +02001396 objv = (Tcl_Obj **)PyMem_Malloc(((size_t)objc) * sizeof(Tcl_Obj *));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 if (objv == NULL) {
1398 PyErr_NoMemory();
1399 objc = 0;
1400 goto finally;
1401 }
1402 }
Guido van Rossum212643f1998-04-29 16:22:14 +00001403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 for (i = 0; i < objc; i++) {
Serhiy Storchaka2b00c492014-05-21 17:12:21 +03001405 PyObject *v = PySequence_Fast_GET_ITEM(args, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 if (v == Py_None) {
1407 objc = i;
1408 break;
1409 }
1410 objv[i] = AsObj(v);
1411 if (!objv[i]) {
1412 /* Reset objc, so it attempts to clear
1413 objects only up to i. */
1414 objc = i;
1415 goto finally;
1416 }
1417 Tcl_IncrRefCount(objv[i]);
1418 }
1419 }
Serhiy Storchaka26861b02015-02-16 20:52:17 +02001420 *pobjc = (int)objc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 return objv;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001422finally:
Serhiy Storchaka26861b02015-02-16 20:52:17 +02001423 Tkapp_CallDeallocArgs(objv, objStore, (int)objc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001425}
Guido van Rossum212643f1998-04-29 16:22:14 +00001426
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001427/* Convert the results of a command call into a Python objects. */
Guido van Rossum632de272000-03-29 00:19:50 +00001428
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001429static PyObject*
1430Tkapp_CallResult(TkappObject *self)
1431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 PyObject *res = NULL;
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001433 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 if(self->wantobjects) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 /* Not sure whether the IncrRef is necessary, but something
1436 may overwrite the interpreter result while we are
1437 converting it. */
1438 Tcl_IncrRefCount(value);
1439 res = FromObj((PyObject*)self, value);
1440 Tcl_DecrRefCount(value);
1441 } else {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001442 res = unicodeFromTclObj(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 }
1444 return res;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001445}
Guido van Rossum632de272000-03-29 00:19:50 +00001446
Benjamin Peterson5879d412009-03-30 14:51:56 +00001447#ifdef WITH_THREAD
1448
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001449/* Tkapp_CallProc is the event procedure that is executed in the context of
1450 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1451 hold the Python lock. */
Barry Warsawfa701a81997-01-16 00:15:11 +00001452
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001453static int
1454Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1455{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 Tcl_Obj *objStore[ARGSZ];
1457 Tcl_Obj **objv;
1458 int objc;
1459 int i;
1460 ENTER_PYTHON
1461 objv = Tkapp_CallArgs(e->args, objStore, &objc);
1462 if (!objv) {
1463 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1464 *(e->res) = NULL;
1465 }
1466 LEAVE_PYTHON
1467 if (!objv)
1468 goto done;
1469 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1470 ENTER_PYTHON
1471 if (i == TCL_ERROR) {
1472 *(e->res) = NULL;
1473 *(e->exc_type) = NULL;
1474 *(e->exc_tb) = NULL;
1475 *(e->exc_value) = PyObject_CallFunction(
1476 Tkinter_TclError, "s",
1477 Tcl_GetStringResult(e->self->interp));
1478 }
1479 else {
1480 *(e->res) = Tkapp_CallResult(e->self);
1481 }
1482 LEAVE_PYTHON
Guilherme Polo491aee22009-02-06 23:16:11 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 Tkapp_CallDeallocArgs(objv, objStore, objc);
Guilherme Polo491aee22009-02-06 23:16:11 +00001485done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 /* Wake up calling thread. */
1487 Tcl_MutexLock(&call_mutex);
1488 Tcl_ConditionNotify(e->done);
1489 Tcl_MutexUnlock(&call_mutex);
1490 return 1;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001491}
1492
Benjamin Peterson5879d412009-03-30 14:51:56 +00001493#endif
1494
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001495/* This is the main entry point for calling a Tcl command.
1496 It supports three cases, with regard to threading:
1497 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
1498 the context of the calling thread.
1499 2. Tcl is threaded, caller of the command is in the interpreter thread:
1500 Execute the command in the calling thread. Since the Tcl lock will
1501 not be used, we can merge that with case 1.
1502 3. Tcl is threaded, caller is in a different thread: Must queue an event to
1503 the interpreter thread. Allocation of Tcl objects needs to occur in the
1504 interpreter thread, so we ship the PyObject* args to the target thread,
1505 and perform processing there. */
1506
1507static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001508Tkapp_Call(PyObject *selfptr, PyObject *args)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001509{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 Tcl_Obj *objStore[ARGSZ];
1511 Tcl_Obj **objv = NULL;
1512 int objc, i;
1513 PyObject *res = NULL;
1514 TkappObject *self = (TkappObject*)selfptr;
1515 int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 /* If args is a single tuple, replace with contents of tuple */
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03001518 if (PyTuple_GET_SIZE(args) == 1) {
1519 PyObject *item = PyTuple_GET_ITEM(args, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 if (PyTuple_Check(item))
1521 args = item;
1522 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001523#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1525 /* We cannot call the command directly. Instead, we must
1526 marshal the parameters to the interpreter thread. */
1527 Tkapp_CallEvent *ev;
1528 Tcl_Condition cond = NULL;
1529 PyObject *exc_type, *exc_value, *exc_tb;
1530 if (!WaitForMainloop(self))
1531 return NULL;
Serhiy Storchaka07940882014-09-11 10:38:54 +03001532 ev = (Tkapp_CallEvent*)attemptckalloc(sizeof(Tkapp_CallEvent));
1533 if (ev == NULL) {
1534 PyErr_NoMemory();
1535 return NULL;
1536 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1538 ev->self = self;
1539 ev->args = args;
1540 ev->res = &res;
1541 ev->exc_type = &exc_type;
1542 ev->exc_value = &exc_value;
1543 ev->exc_tb = &exc_tb;
1544 ev->done = &cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 if (res == NULL) {
1549 if (exc_type)
1550 PyErr_Restore(exc_type, exc_value, exc_tb);
1551 else
1552 PyErr_SetObject(Tkinter_TclError, exc_value);
1553 }
1554 Tcl_ConditionFinalize(&cond);
1555 }
1556 else
Martin v. Löwisa9656492003-03-30 08:44:58 +00001557#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 {
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 objv = Tkapp_CallArgs(args, objStore, &objc);
1561 if (!objv)
1562 return NULL;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001564 ENTER_TCL
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 ENTER_OVERLAP
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 if (i == TCL_ERROR)
1571 Tkinter_Error(selfptr);
1572 else
1573 res = Tkapp_CallResult(self);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 LEAVE_OVERLAP_TCL
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 Tkapp_CallDeallocArgs(objv, objStore, objc);
1578 }
1579 return res;
Barry Warsawfa701a81997-01-16 00:15:11 +00001580}
1581
1582
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001583/*[clinic input]
1584_tkinter.tkapp.eval
1585
1586 script: str
1587 /
1588
1589[clinic start generated code]*/
1590
Barry Warsawfa701a81997-01-16 00:15:11 +00001591static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001592_tkinter_tkapp_eval_impl(TkappObject *self, const char *script)
1593/*[clinic end generated code: output=24b79831f700dea0 input=481484123a455f22]*/
Guido van Rossum18468821994-06-20 07:49:28 +00001594{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 PyObject *res = NULL;
1596 int err;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001597
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001598 CHECK_STRING_LENGTH(script);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 ENTER_TCL
1602 err = Tcl_Eval(Tkapp_Interp(self), script);
1603 ENTER_OVERLAP
1604 if (err == TCL_ERROR)
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001605 res = Tkinter_Error((PyObject *)self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 else
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001607 res = unicodeFromTclString(Tkapp_Result(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 LEAVE_OVERLAP_TCL
1609 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001610}
1611
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001612/*[clinic input]
1613_tkinter.tkapp.evalfile
1614
1615 fileName: str
1616 /
1617
1618[clinic start generated code]*/
1619
Guido van Rossum18468821994-06-20 07:49:28 +00001620static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001621_tkinter_tkapp_evalfile_impl(TkappObject *self, const char *fileName)
1622/*[clinic end generated code: output=63be88dcee4f11d3 input=873ab707e5e947e1]*/
Guido van Rossum18468821994-06-20 07:49:28 +00001623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 PyObject *res = NULL;
1625 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001626
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001627 CHECK_STRING_LENGTH(fileName);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 ENTER_TCL
1631 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
1632 ENTER_OVERLAP
1633 if (err == TCL_ERROR)
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001634 res = Tkinter_Error((PyObject *)self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 else
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001636 res = unicodeFromTclString(Tkapp_Result(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 LEAVE_OVERLAP_TCL
1638 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001639}
1640
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001641/*[clinic input]
1642_tkinter.tkapp.record
1643
1644 script: str
1645 /
1646
1647[clinic start generated code]*/
1648
Guido van Rossum18468821994-06-20 07:49:28 +00001649static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001650_tkinter_tkapp_record_impl(TkappObject *self, const char *script)
1651/*[clinic end generated code: output=0ffe08a0061730df input=c0b0db5a21412cac]*/
Guido van Rossum18468821994-06-20 07:49:28 +00001652{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653 PyObject *res = NULL;
1654 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001655
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001656 CHECK_STRING_LENGTH(script);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 ENTER_TCL
1660 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
1661 ENTER_OVERLAP
1662 if (err == TCL_ERROR)
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001663 res = Tkinter_Error((PyObject *)self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 else
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001665 res = unicodeFromTclString(Tkapp_Result(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 LEAVE_OVERLAP_TCL
1667 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001668}
1669
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001670/*[clinic input]
1671_tkinter.tkapp.adderrinfo
Guido van Rossum18468821994-06-20 07:49:28 +00001672
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001673 msg: str
1674 /
1675
1676[clinic start generated code]*/
1677
1678static PyObject *
1679_tkinter_tkapp_adderrinfo_impl(TkappObject *self, const char *msg)
1680/*[clinic end generated code: output=0e222ee2050eb357 input=4971399317d4c136]*/
1681{
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001682 CHECK_STRING_LENGTH(msg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 ENTER_TCL
1686 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
1687 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001688
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03001689 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00001690}
1691
Barry Warsawfa701a81997-01-16 00:15:11 +00001692
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001693
Guido van Rossum18468821994-06-20 07:49:28 +00001694/** Tcl Variable **/
1695
Benjamin Peterson5879d412009-03-30 14:51:56 +00001696typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
1697
1698#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001699TCL_DECLARE_MUTEX(var_mutex)
1700
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001701typedef struct VarEvent {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 Tcl_Event ev; /* must be first */
1703 PyObject *self;
1704 PyObject *args;
1705 int flags;
1706 EventFunc func;
1707 PyObject **res;
1708 PyObject **exc_type;
1709 PyObject **exc_val;
1710 Tcl_Condition *cond;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001711} VarEvent;
Benjamin Peterson5879d412009-03-30 14:51:56 +00001712#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001713
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001714/*[python]
1715
1716class varname_converter(CConverter):
1717 type = 'const char *'
1718 converter = 'varname_converter'
1719
1720[python]*/
1721/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
1722
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001723static int
1724varname_converter(PyObject *in, void *_out)
1725{
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001726 char *s;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001727 const char **out = (const char**)_out;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 if (PyBytes_Check(in)) {
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03001729 if (PyBytes_GET_SIZE(in) > INT_MAX) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001730 PyErr_SetString(PyExc_OverflowError, "bytes object is too long");
1731 return 0;
1732 }
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03001733 s = PyBytes_AS_STRING(in);
1734 if (strlen(s) != (size_t)PyBytes_GET_SIZE(in)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001735 PyErr_SetString(PyExc_ValueError, "embedded null byte");
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001736 return 0;
1737 }
1738 *out = s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 return 1;
1740 }
1741 if (PyUnicode_Check(in)) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001742 Py_ssize_t size;
1743 s = PyUnicode_AsUTF8AndSize(in, &size);
Christian Heimesd33491e2014-02-05 00:29:17 +01001744 if (s == NULL) {
1745 return 0;
1746 }
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001747 if (size > INT_MAX) {
1748 PyErr_SetString(PyExc_OverflowError, "string is too long");
1749 return 0;
1750 }
Victor Stinner706768c2014-08-16 01:03:39 +02001751 if (strlen(s) != (size_t)size) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001752 PyErr_SetString(PyExc_ValueError, "embedded null character");
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001753 return 0;
1754 }
1755 *out = s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 return 1;
1757 }
1758 if (PyTclObject_Check(in)) {
1759 *out = PyTclObject_TclString(in);
1760 return 1;
1761 }
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001762 PyErr_Format(PyExc_TypeError,
1763 "must be str, bytes or Tcl_Obj, not %.50s",
1764 in->ob_type->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 return 0;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001766}
Martin v. Löwis1869ec52003-05-01 05:47:00 +00001767
Benjamin Peterson5879d412009-03-30 14:51:56 +00001768#ifdef WITH_THREAD
1769
Martin v. Löwis59683e82008-06-13 07:50:45 +00001770static void
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001771var_perform(VarEvent *ev)
1772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1774 if (!*(ev->res)) {
1775 PyObject *exc, *val, *tb;
1776 PyErr_Fetch(&exc, &val, &tb);
1777 PyErr_NormalizeException(&exc, &val, &tb);
1778 *(ev->exc_type) = exc;
1779 *(ev->exc_val) = val;
Serhiy Storchaka3ec5f422016-10-28 12:14:34 +03001780 Py_XDECREF(tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 }
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001782
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001783}
1784
1785static int
1786var_proc(VarEvent* ev, int flags)
1787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 ENTER_PYTHON
1789 var_perform(ev);
1790 Tcl_MutexLock(&var_mutex);
1791 Tcl_ConditionNotify(ev->cond);
1792 Tcl_MutexUnlock(&var_mutex);
1793 LEAVE_PYTHON
1794 return 1;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001795}
1796
Benjamin Peterson5879d412009-03-30 14:51:56 +00001797#endif
1798
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001799static PyObject*
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001800var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001801{
Martin v. Löwisa9656492003-03-30 08:44:58 +00001802#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 TkappObject *self = (TkappObject*)selfptr;
1804 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 VarEvent *ev;
1806 PyObject *res, *exc_type, *exc_val;
1807 Tcl_Condition cond = NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00001808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 /* The current thread is not the interpreter thread. Marshal
1810 the call to the interpreter thread, then wait for
1811 completion. */
1812 if (!WaitForMainloop(self))
1813 return NULL;
Martin v. Löwisee24e9c2003-04-15 20:33:20 +00001814
Serhiy Storchaka07940882014-09-11 10:38:54 +03001815 ev = (VarEvent*)attemptckalloc(sizeof(VarEvent));
1816 if (ev == NULL) {
1817 PyErr_NoMemory();
1818 return NULL;
1819 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 ev->self = selfptr;
1821 ev->args = args;
1822 ev->flags = flags;
1823 ev->func = func;
1824 ev->res = &res;
1825 ev->exc_type = &exc_type;
1826 ev->exc_val = &exc_val;
1827 ev->cond = &cond;
1828 ev->ev.proc = (Tcl_EventProc*)var_proc;
1829 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
1830 Tcl_ConditionFinalize(&cond);
1831 if (!res) {
1832 PyErr_SetObject(exc_type, exc_val);
1833 Py_DECREF(exc_type);
1834 Py_DECREF(exc_val);
1835 return NULL;
1836 }
1837 return res;
1838 }
Martin v. Löwisa9656492003-03-30 08:44:58 +00001839#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 /* Tcl is not threaded, or this is the interpreter thread. */
1841 return func(selfptr, args, flags);
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00001842}
1843
Guido van Rossum18468821994-06-20 07:49:28 +00001844static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001845SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001846{
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001847 const char *name1, *name2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 PyObject *newValue;
1849 PyObject *res = NULL;
1850 Tcl_Obj *newval, *ok;
Guido van Rossum18468821994-06-20 07:49:28 +00001851
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001852 switch (PyTuple_GET_SIZE(args)) {
1853 case 2:
1854 if (!PyArg_ParseTuple(args, "O&O:setvar",
1855 varname_converter, &name1, &newValue))
1856 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 /* XXX Acquire tcl lock??? */
1858 newval = AsObj(newValue);
1859 if (newval == NULL)
1860 return NULL;
1861 ENTER_TCL
1862 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1863 newval, flags);
1864 ENTER_OVERLAP
1865 if (!ok)
1866 Tkinter_Error(self);
1867 else {
1868 res = Py_None;
1869 Py_INCREF(res);
1870 }
1871 LEAVE_OVERLAP_TCL
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001872 break;
1873 case 3:
1874 if (!PyArg_ParseTuple(args, "ssO:setvar",
1875 &name1, &name2, &newValue))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001877 CHECK_STRING_LENGTH(name1);
1878 CHECK_STRING_LENGTH(name2);
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001879 /* XXX must hold tcl lock already??? */
1880 newval = AsObj(newValue);
1881 ENTER_TCL
1882 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1883 ENTER_OVERLAP
1884 if (!ok)
1885 Tkinter_Error(self);
1886 else {
1887 res = Py_None;
1888 Py_INCREF(res);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 }
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001890 LEAVE_OVERLAP_TCL
1891 break;
1892 default:
1893 PyErr_SetString(PyExc_TypeError, "setvar requires 2 to 3 arguments");
1894 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 }
1896 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001897}
1898
1899static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001900Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001903}
1904
1905static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001906Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001909}
1910
Barry Warsawfa701a81997-01-16 00:15:11 +00001911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912
Guido van Rossum18468821994-06-20 07:49:28 +00001913static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001914GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001915{
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001916 const char *name1, *name2=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 PyObject *res = NULL;
1918 Tcl_Obj *tres;
Guido van Rossum18468821994-06-20 07:49:28 +00001919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 if (!PyArg_ParseTuple(args, "O&|s:getvar",
1921 varname_converter, &name1, &name2))
1922 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001923
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001924 CHECK_STRING_LENGTH(name2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 ENTER_TCL
1926 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1927 ENTER_OVERLAP
1928 if (tres == NULL) {
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +03001929 PyErr_SetString(Tkinter_TclError,
1930 Tcl_GetStringResult(Tkapp_Interp(self)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 } else {
1932 if (((TkappObject*)self)->wantobjects) {
1933 res = FromObj(self, tres);
1934 }
1935 else {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02001936 res = unicodeFromTclObj(tres);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 }
1938 }
1939 LEAVE_OVERLAP_TCL
1940 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001941}
1942
1943static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001944Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001947}
1948
1949static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001950Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001953}
1954
Barry Warsawfa701a81997-01-16 00:15:11 +00001955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956
Guido van Rossum18468821994-06-20 07:49:28 +00001957static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001958UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001959{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 char *name1, *name2=NULL;
1961 int code;
1962 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
1965 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001966
Serhiy Storchaka79851d72014-05-30 14:24:03 +03001967 CHECK_STRING_LENGTH(name1);
1968 CHECK_STRING_LENGTH(name2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 ENTER_TCL
1970 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1971 ENTER_OVERLAP
1972 if (code == TCL_ERROR)
1973 res = Tkinter_Error(self);
1974 else {
1975 Py_INCREF(Py_None);
1976 res = Py_None;
1977 }
1978 LEAVE_OVERLAP_TCL
1979 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001980}
1981
1982static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001983Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001984{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001986}
1987
1988static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001989Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001990{
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +03001991 return var_invoke(UnsetVar, self, args,
1992 TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001993}
1994
Barry Warsawfa701a81997-01-16 00:15:11 +00001995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996
Guido van Rossum18468821994-06-20 07:49:28 +00001997/** Tcl to Python **/
1998
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03001999/*[clinic input]
2000_tkinter.tkapp.getint
2001
2002 arg: object
2003 /
2004
2005[clinic start generated code]*/
2006
Guido van Rossum18468821994-06-20 07:49:28 +00002007static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002008_tkinter_tkapp_getint(TkappObject *self, PyObject *arg)
2009/*[clinic end generated code: output=88cf293fae307cfe input=034026997c5b91f8]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002010{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002011 char *s;
Serhiy Storchakaea134da2015-04-02 18:46:50 +03002012 Tcl_Obj *value;
2013 PyObject *result;
Guido van Rossum18468821994-06-20 07:49:28 +00002014
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002015 if (PyLong_Check(arg)) {
2016 Py_INCREF(arg);
2017 return arg;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 }
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002019
Serhiy Storchaka645058d2015-05-06 14:00:04 +03002020 if (PyTclObject_Check(arg)) {
2021 value = ((PyTclObject*)arg)->value;
2022 Tcl_IncrRefCount(value);
2023 }
2024 else {
2025 if (!PyArg_Parse(arg, "s:getint", &s))
2026 return NULL;
2027 CHECK_STRING_LENGTH(s);
2028 value = Tcl_NewStringObj(s, -1);
2029 if (value == NULL)
2030 return Tkinter_Error((PyObject *)self);
2031 }
Serhiy Storchakaea134da2015-04-02 18:46:50 +03002032 /* Don't use Tcl_GetInt() because it returns ambiguous result for value
2033 in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform).
2034
2035 Prefer bignum because Tcl_GetWideIntFromObj returns ambiguous result for
2036 value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform).
2037 */
2038#ifdef HAVE_LIBTOMMAMTH
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002039 result = fromBignumObj((PyObject *)self, value);
Serhiy Storchakaea134da2015-04-02 18:46:50 +03002040#else
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002041 result = fromWideIntObj((PyObject *)self, value);
Serhiy Storchakaea134da2015-04-02 18:46:50 +03002042#endif
2043 Tcl_DecrRefCount(value);
2044 if (result != NULL || PyErr_Occurred())
2045 return result;
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002046 return Tkinter_Error((PyObject *)self);
Guido van Rossum18468821994-06-20 07:49:28 +00002047}
2048
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002049/*[clinic input]
2050_tkinter.tkapp.getdouble
2051
2052 arg: object
2053 /
2054
2055[clinic start generated code]*/
2056
Guido van Rossum18468821994-06-20 07:49:28 +00002057static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002058_tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg)
2059/*[clinic end generated code: output=c52b138bd8b956b9 input=22015729ce9ef7f8]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002060{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 char *s;
2062 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00002063
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002064 if (PyFloat_Check(arg)) {
2065 Py_INCREF(arg);
2066 return arg;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 }
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002068
Serhiy Storchaka645058d2015-05-06 14:00:04 +03002069 if (PyNumber_Check(arg)) {
2070 return PyNumber_Float(arg);
2071 }
2072
2073 if (PyTclObject_Check(arg)) {
2074 if (Tcl_GetDoubleFromObj(Tkapp_Interp(self),
2075 ((PyTclObject*)arg)->value,
2076 &v) == TCL_ERROR)
2077 return Tkinter_Error((PyObject *)self);
2078 return PyFloat_FromDouble(v);
2079 }
2080
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002081 if (!PyArg_Parse(arg, "s:getdouble", &s))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03002083 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002085 return Tkinter_Error((PyObject *)self);
Serhiy Storchaka645058d2015-05-06 14:00:04 +03002086 return PyFloat_FromDouble(v);
Guido van Rossum18468821994-06-20 07:49:28 +00002087}
2088
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002089/*[clinic input]
2090_tkinter.tkapp.getboolean
2091
2092 arg: object
2093 /
2094
2095[clinic start generated code]*/
2096
Guido van Rossum18468821994-06-20 07:49:28 +00002097static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002098_tkinter_tkapp_getboolean(TkappObject *self, PyObject *arg)
2099/*[clinic end generated code: output=726a9ae445821d91 input=7f11248ef8f8776e]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 char *s;
2102 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00002103
Serhiy Storchaka9a6e2012015-04-04 12:43:01 +03002104 if (PyLong_Check(arg)) { /* int or bool */
2105 return PyBool_FromLong(Py_SIZE(arg) != 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 }
Serhiy Storchaka9a6e2012015-04-04 12:43:01 +03002107
2108 if (PyTclObject_Check(arg)) {
2109 if (Tcl_GetBooleanFromObj(Tkapp_Interp(self),
2110 ((PyTclObject*)arg)->value,
2111 &v) == TCL_ERROR)
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002112 return Tkinter_Error((PyObject *)self);
Serhiy Storchaka9a6e2012015-04-04 12:43:01 +03002113 return PyBool_FromLong(v);
2114 }
2115
2116 if (!PyArg_Parse(arg, "s:getboolean", &s))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002117 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03002118 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002119 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002120 return Tkinter_Error((PyObject *)self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 return PyBool_FromLong(v);
Guido van Rossum18468821994-06-20 07:49:28 +00002122}
2123
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002124/*[clinic input]
2125_tkinter.tkapp.exprstring
2126
2127 s: str
2128 /
2129
2130[clinic start generated code]*/
2131
Guido van Rossum18468821994-06-20 07:49:28 +00002132static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002133_tkinter_tkapp_exprstring_impl(TkappObject *self, const char *s)
2134/*[clinic end generated code: output=beda323d3ed0abb1 input=fa78f751afb2f21b]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 PyObject *res = NULL;
2137 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00002138
Serhiy Storchaka79851d72014-05-30 14:24:03 +03002139 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002142 ENTER_TCL
2143 retval = Tcl_ExprString(Tkapp_Interp(self), s);
2144 ENTER_OVERLAP
2145 if (retval == TCL_ERROR)
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002146 res = Tkinter_Error((PyObject *)self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002147 else
Serhiy Storchaka1317e142014-02-03 21:24:07 +02002148 res = unicodeFromTclString(Tkapp_Result(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 LEAVE_OVERLAP_TCL
2150 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00002151}
2152
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002153/*[clinic input]
2154_tkinter.tkapp.exprlong
2155
2156 s: str
2157 /
2158
2159[clinic start generated code]*/
2160
Guido van Rossum18468821994-06-20 07:49:28 +00002161static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002162_tkinter_tkapp_exprlong_impl(TkappObject *self, const char *s)
2163/*[clinic end generated code: output=5d6a46b63c6ebcf9 input=11bd7eee0c57b4dc]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 PyObject *res = NULL;
2166 int retval;
2167 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00002168
Serhiy Storchaka79851d72014-05-30 14:24:03 +03002169 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 CHECK_TCL_APPARTMENT;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 ENTER_TCL
2173 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
2174 ENTER_OVERLAP
2175 if (retval == TCL_ERROR)
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002176 res = Tkinter_Error((PyObject *)self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 else
Serhiy Storchaka8d0f6202015-05-06 14:19:22 +03002178 res = PyLong_FromLong(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 LEAVE_OVERLAP_TCL
2180 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00002181}
2182
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002183/*[clinic input]
2184_tkinter.tkapp.exprdouble
2185
2186 s: str
2187 /
2188
2189[clinic start generated code]*/
2190
Guido van Rossum18468821994-06-20 07:49:28 +00002191static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002192_tkinter_tkapp_exprdouble_impl(TkappObject *self, const char *s)
2193/*[clinic end generated code: output=ff78df1081ea4158 input=ff02bc11798832d5]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002194{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002195 PyObject *res = NULL;
2196 double v;
2197 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00002198
Serhiy Storchaka79851d72014-05-30 14:24:03 +03002199 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002200 CHECK_TCL_APPARTMENT;
2201 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
2202 ENTER_TCL
2203 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
2204 ENTER_OVERLAP
2205 PyFPE_END_PROTECT(retval)
2206 if (retval == TCL_ERROR)
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002207 res = Tkinter_Error((PyObject *)self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002208 else
Serhiy Storchaka8d0f6202015-05-06 14:19:22 +03002209 res = PyFloat_FromDouble(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002210 LEAVE_OVERLAP_TCL
2211 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00002212}
2213
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002214/*[clinic input]
2215_tkinter.tkapp.exprboolean
2216
2217 s: str
2218 /
2219
2220[clinic start generated code]*/
2221
Guido van Rossum18468821994-06-20 07:49:28 +00002222static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002223_tkinter_tkapp_exprboolean_impl(TkappObject *self, const char *s)
2224/*[clinic end generated code: output=8b28038c22887311 input=c8c66022bdb8d5d3]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 PyObject *res = NULL;
2227 int retval;
2228 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00002229
Serhiy Storchaka79851d72014-05-30 14:24:03 +03002230 CHECK_STRING_LENGTH(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 CHECK_TCL_APPARTMENT;
2232 ENTER_TCL
2233 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
2234 ENTER_OVERLAP
2235 if (retval == TCL_ERROR)
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002236 res = Tkinter_Error((PyObject *)self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 else
Serhiy Storchaka8d0f6202015-05-06 14:19:22 +03002238 res = PyLong_FromLong(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 LEAVE_OVERLAP_TCL
2240 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00002241}
2242
Barry Warsawfa701a81997-01-16 00:15:11 +00002243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002245/*[clinic input]
2246_tkinter.tkapp.splitlist
2247
2248 arg: object
2249 /
2250
2251[clinic start generated code]*/
2252
Guido van Rossum18468821994-06-20 07:49:28 +00002253static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002254_tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg)
2255/*[clinic end generated code: output=13b51d34386d36fb input=2b2e13351e3c0b53]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 char *list;
2258 int argc;
Serhiy Storchaka6716d602014-07-30 19:19:21 +03002259 const char **argv;
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002260 PyObject *v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00002262
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002263 if (PyTclObject_Check(arg)) {
2264 int objc;
2265 Tcl_Obj **objv;
2266 if (Tcl_ListObjGetElements(Tkapp_Interp(self),
2267 ((PyTclObject*)arg)->value,
2268 &objc, &objv) == TCL_ERROR) {
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002269 return Tkinter_Error((PyObject *)self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 }
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002271 if (!(v = PyTuple_New(objc)))
2272 return NULL;
2273 for (i = 0; i < objc; i++) {
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002274 PyObject *s = FromObj((PyObject*)self, objv[i]);
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03002275 if (!s) {
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002276 Py_DECREF(v);
2277 return NULL;
2278 }
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03002279 PyTuple_SET_ITEM(v, i, s);
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002280 }
2281 return v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 }
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002283 if (PyTuple_Check(arg)) {
2284 Py_INCREF(arg);
2285 return arg;
2286 }
Serhiy Storchaka2b00c492014-05-21 17:12:21 +03002287 if (PyList_Check(arg)) {
2288 return PySequence_Tuple(arg);
2289 }
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002290
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002291 if (!PyArg_Parse(arg, "et:splitlist", "utf-8", &list))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002292 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002293
Serhiy Storchaka79851d72014-05-30 14:24:03 +03002294 CHECK_STRING_LENGTH(list);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 if (Tcl_SplitList(Tkapp_Interp(self), list,
2296 &argc, &argv) == TCL_ERROR) {
2297 PyMem_Free(list);
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002298 return Tkinter_Error((PyObject *)self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 }
Guido van Rossum18468821994-06-20 07:49:28 +00002300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002301 if (!(v = PyTuple_New(argc)))
2302 goto finally;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 for (i = 0; i < argc; i++) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02002305 PyObject *s = unicodeFromTclString(argv[i]);
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03002306 if (!s) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 Py_DECREF(v);
2308 v = NULL;
2309 goto finally;
2310 }
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03002311 PyTuple_SET_ITEM(v, i, s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 }
Guido van Rossum18468821994-06-20 07:49:28 +00002313
Barry Warsawfa701a81997-01-16 00:15:11 +00002314 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 ckfree(FREECAST argv);
2316 PyMem_Free(list);
2317 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00002318}
2319
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002320/*[clinic input]
2321_tkinter.tkapp.split
2322
2323 arg: object
2324 /
2325
2326[clinic start generated code]*/
2327
Guido van Rossum18468821994-06-20 07:49:28 +00002328static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002329_tkinter_tkapp_split(TkappObject *self, PyObject *arg)
2330/*[clinic end generated code: output=e08ad832363facfd input=a1c78349eacaa140]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002331{
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002332 PyObject *v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002333 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00002334
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002335 if (PyTclObject_Check(arg)) {
2336 Tcl_Obj *value = ((PyTclObject*)arg)->value;
2337 int objc;
2338 Tcl_Obj **objv;
2339 int i;
2340 if (Tcl_ListObjGetElements(Tkapp_Interp(self), value,
2341 &objc, &objv) == TCL_ERROR) {
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002342 return FromObj((PyObject*)self, value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002343 }
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002344 if (objc == 0)
2345 return PyUnicode_FromString("");
2346 if (objc == 1)
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002347 return FromObj((PyObject*)self, objv[0]);
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002348 if (!(v = PyTuple_New(objc)))
2349 return NULL;
2350 for (i = 0; i < objc; i++) {
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002351 PyObject *s = FromObj((PyObject*)self, objv[i]);
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03002352 if (!s) {
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002353 Py_DECREF(v);
2354 return NULL;
2355 }
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03002356 PyTuple_SET_ITEM(v, i, s);
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002357 }
2358 return v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002359 }
Serhiy Storchaka2b00c492014-05-21 17:12:21 +03002360 if (PyTuple_Check(arg) || PyList_Check(arg))
Serhiy Storchaka203eb312013-08-22 17:40:31 +03002361 return SplitObj(arg);
2362
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002363 if (!PyArg_Parse(arg, "et:split", "utf-8", &list))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 return NULL;
Serhiy Storchaka79851d72014-05-30 14:24:03 +03002365 CHECK_STRING_LENGTH(list);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002366 v = Split(list);
2367 PyMem_Free(list);
2368 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00002369}
2370
Barry Warsawfa701a81997-01-16 00:15:11 +00002371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002372
Guido van Rossum18468821994-06-20 07:49:28 +00002373/** Tcl Command **/
2374
Guido van Rossum00d93061998-05-28 23:06:38 +00002375/* Client data struct */
2376typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377 PyObject *self;
2378 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002379} PythonCmd_ClientData;
2380
2381static int
Fred Drake509d79a2000-07-08 04:04:38 +00002382PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00002383{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 errorInCmd = 1;
2385 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2386 LEAVE_PYTHON
2387 return TCL_ERROR;
Guido van Rossum00d93061998-05-28 23:06:38 +00002388}
2389
Guido van Rossum18468821994-06-20 07:49:28 +00002390/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00002391 * function or method.
2392 */
Guido van Rossum18468821994-06-20 07:49:28 +00002393static int
Serhiy Storchaka6716d602014-07-30 19:19:21 +03002394PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00002395{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002396 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Brett Cannonb94767f2011-02-22 20:15:44 +00002397 PyObject *func, *arg, *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 int i, rv;
2399 Tcl_Obj *obj_res;
Guido van Rossum18468821994-06-20 07:49:28 +00002400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002401 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 /* TBD: no error checking here since we know, via the
2404 * Tkapp_CreateCommand() that the client data is a two-tuple
2405 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 /* Create argument list (argv1, ..., argvN) */
2409 if (!(arg = PyTuple_New(argc - 1)))
2410 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00002411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 for (i = 0; i < (argc - 1); i++) {
Serhiy Storchaka1317e142014-02-03 21:24:07 +02002413 PyObject *s = unicodeFromTclString(argv[i + 1]);
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03002414 if (!s) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 Py_DECREF(arg);
2416 return PythonCmd_Error(interp);
2417 }
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03002418 PyTuple_SET_ITEM(arg, i, s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 }
2420 res = PyEval_CallObject(func, arg);
2421 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00002422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 if (res == NULL)
2424 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00002425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 obj_res = AsObj(res);
2427 if (obj_res == NULL) {
2428 Py_DECREF(res);
2429 return PythonCmd_Error(interp);
2430 }
2431 else {
2432 Tcl_SetObjResult(interp, obj_res);
2433 rv = TCL_OK;
2434 }
Guido van Rossum2834b972000-10-06 16:58:26 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 Py_DECREF(res);
Barry Warsawfa701a81997-01-16 00:15:11 +00002437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002438 LEAVE_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002440 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00002441}
2442
2443static void
Fred Drake509d79a2000-07-08 04:04:38 +00002444PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00002445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Guido van Rossum00d93061998-05-28 23:06:38 +00002447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002448 ENTER_PYTHON
2449 Py_XDECREF(data->self);
2450 Py_XDECREF(data->func);
2451 PyMem_DEL(data);
2452 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00002453}
2454
Barry Warsawfa701a81997-01-16 00:15:11 +00002455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002456
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002457
Benjamin Peterson5879d412009-03-30 14:51:56 +00002458#ifdef WITH_THREAD
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002459TCL_DECLARE_MUTEX(command_mutex)
2460
2461typedef struct CommandEvent{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 Tcl_Event ev;
2463 Tcl_Interp* interp;
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002464 const char *name;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 int create;
2466 int *status;
2467 ClientData *data;
2468 Tcl_Condition *done;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002469} CommandEvent;
2470
2471static int
2472Tkapp_CommandProc(CommandEvent *ev, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00002473{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002474 if (ev->create)
2475 *ev->status = Tcl_CreateCommand(
2476 ev->interp, ev->name, PythonCmd,
2477 ev->data, PythonCmdDelete) == NULL;
2478 else
2479 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2480 Tcl_MutexLock(&command_mutex);
2481 Tcl_ConditionNotify(ev->done);
2482 Tcl_MutexUnlock(&command_mutex);
2483 return 1;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002484}
Benjamin Peterson5879d412009-03-30 14:51:56 +00002485#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002486
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002487/*[clinic input]
2488_tkinter.tkapp.createcommand
2489
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002490 name: str
2491 func: object
2492 /
2493
2494[clinic start generated code]*/
2495
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002496static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002497_tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name,
2498 PyObject *func)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03002499/*[clinic end generated code: output=2a1c79a4ee2af410 input=255785cb70edc6a0]*/
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002501 PythonCmd_ClientData *data;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 int err;
Guido van Rossum35d43371997-08-02 00:09:09 +00002503
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002504 CHECK_STRING_LENGTH(name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002505 if (!PyCallable_Check(func)) {
2506 PyErr_SetString(PyExc_TypeError, "command not callable");
2507 return NULL;
2508 }
Guido van Rossum18468821994-06-20 07:49:28 +00002509
Martin v. Löwisa9656492003-03-30 08:44:58 +00002510#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002511 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
2512 !WaitForMainloop(self))
2513 return NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00002514#endif
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002516 data = PyMem_NEW(PythonCmd_ClientData, 1);
2517 if (!data)
2518 return PyErr_NoMemory();
2519 Py_INCREF(self);
2520 Py_INCREF(func);
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002521 data->self = (PyObject *) self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002522 data->func = func;
Benjamin Peterson5879d412009-03-30 14:51:56 +00002523#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002524 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2525 Tcl_Condition cond = NULL;
Serhiy Storchaka07940882014-09-11 10:38:54 +03002526 CommandEvent *ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent));
2527 if (ev == NULL) {
2528 PyErr_NoMemory();
2529 PyMem_DEL(data);
2530 return NULL;
2531 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002532 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2533 ev->interp = self->interp;
2534 ev->create = 1;
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002535 ev->name = name;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002536 ev->data = (ClientData)data;
2537 ev->status = &err;
2538 ev->done = &cond;
2539 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
2540 Tcl_ConditionFinalize(&cond);
2541 }
2542 else
Benjamin Peterson5879d412009-03-30 14:51:56 +00002543#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002544 {
2545 ENTER_TCL
2546 err = Tcl_CreateCommand(
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002547 Tkapp_Interp(self), name, PythonCmd,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002548 (ClientData)data, PythonCmdDelete) == NULL;
2549 LEAVE_TCL
2550 }
2551 if (err) {
2552 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
2553 PyMem_DEL(data);
2554 return NULL;
2555 }
Guido van Rossum18468821994-06-20 07:49:28 +00002556
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002557 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002558}
2559
Barry Warsawfa701a81997-01-16 00:15:11 +00002560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002562/*[clinic input]
2563_tkinter.tkapp.deletecommand
2564
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002565 name: str
2566 /
2567
2568[clinic start generated code]*/
2569
Guido van Rossum18468821994-06-20 07:49:28 +00002570static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002571_tkinter_tkapp_deletecommand_impl(TkappObject *self, const char *name)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03002572/*[clinic end generated code: output=a67e8cb5845e0d2d input=53e9952eae1f85f5]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002573{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002574 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00002575
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002576 CHECK_STRING_LENGTH(name);
Benjamin Peterson5879d412009-03-30 14:51:56 +00002577
2578#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002579 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2580 Tcl_Condition cond = NULL;
2581 CommandEvent *ev;
Serhiy Storchaka07940882014-09-11 10:38:54 +03002582 ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent));
2583 if (ev == NULL) {
2584 PyErr_NoMemory();
2585 return NULL;
2586 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002587 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2588 ev->interp = self->interp;
2589 ev->create = 0;
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002590 ev->name = name;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002591 ev->status = &err;
2592 ev->done = &cond;
2593 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
2594 &command_mutex);
2595 Tcl_ConditionFinalize(&cond);
2596 }
2597 else
Benjamin Peterson5879d412009-03-30 14:51:56 +00002598#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002599 {
2600 ENTER_TCL
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002601 err = Tcl_DeleteCommand(self->interp, name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002602 LEAVE_TCL
2603 }
2604 if (err == -1) {
2605 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2606 return NULL;
2607 }
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002608 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002609}
2610
Barry Warsawfa701a81997-01-16 00:15:11 +00002611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002612
Guido van Rossum00d93061998-05-28 23:06:38 +00002613#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00002614/** File Handler **/
2615
Guido van Rossum00d93061998-05-28 23:06:38 +00002616typedef struct _fhcdata {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002617 PyObject *func;
2618 PyObject *file;
2619 int id;
2620 struct _fhcdata *next;
Guido van Rossum00d93061998-05-28 23:06:38 +00002621} FileHandler_ClientData;
2622
2623static FileHandler_ClientData *HeadFHCD;
2624
2625static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00002626NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002628 FileHandler_ClientData *p;
2629 p = PyMem_NEW(FileHandler_ClientData, 1);
2630 if (p != NULL) {
2631 Py_XINCREF(func);
2632 Py_XINCREF(file);
2633 p->func = func;
2634 p->file = file;
2635 p->id = id;
2636 p->next = HeadFHCD;
2637 HeadFHCD = p;
2638 }
2639 return p;
Guido van Rossum00d93061998-05-28 23:06:38 +00002640}
2641
2642static void
Fred Drake509d79a2000-07-08 04:04:38 +00002643DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00002644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002645 FileHandler_ClientData *p, **pp;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002647 pp = &HeadFHCD;
2648 while ((p = *pp) != NULL) {
2649 if (p->id == id) {
2650 *pp = p->next;
2651 Py_XDECREF(p->func);
2652 Py_XDECREF(p->file);
2653 PyMem_DEL(p);
2654 }
2655 else
2656 pp = &p->next;
2657 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002658}
2659
Guido van Rossuma597dde1995-01-10 20:56:29 +00002660static void
Fred Drake509d79a2000-07-08 04:04:38 +00002661FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00002662{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002663 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
2664 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00002665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002666 ENTER_PYTHON
2667 func = data->func;
2668 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00002669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002670 arg = Py_BuildValue("(Oi)", file, (long) mask);
2671 res = PyEval_CallObject(func, arg);
2672 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002674 if (res == NULL) {
2675 errorInCmd = 1;
2676 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2677 }
2678 Py_XDECREF(res);
2679 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00002680}
2681
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002682/*[clinic input]
2683_tkinter.tkapp.createfilehandler
2684
2685 file: object
2686 mask: int
2687 func: object
2688 /
2689
2690[clinic start generated code]*/
2691
Guido van Rossum18468821994-06-20 07:49:28 +00002692static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002693_tkinter_tkapp_createfilehandler_impl(TkappObject *self, PyObject *file,
2694 int mask, PyObject *func)
2695/*[clinic end generated code: output=f73ce82de801c353 input=84943a5286e47947]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002696{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002697 FileHandler_ClientData *data;
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002698 int tfile;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002700 CHECK_TCL_APPARTMENT;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002702 tfile = PyObject_AsFileDescriptor(file);
2703 if (tfile < 0)
2704 return NULL;
2705 if (!PyCallable_Check(func)) {
2706 PyErr_SetString(PyExc_TypeError, "bad argument list");
2707 return NULL;
2708 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002710 data = NewFHCD(func, file, tfile);
2711 if (data == NULL)
2712 return NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002713
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002714 /* Ought to check for null Tcl_File object... */
2715 ENTER_TCL
2716 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
2717 LEAVE_TCL
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002718 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002719}
2720
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002721/*[clinic input]
2722_tkinter.tkapp.deletefilehandler
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002723
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002724 file: object
2725 /
2726
2727[clinic start generated code]*/
2728
2729static PyObject *
2730_tkinter_tkapp_deletefilehandler(TkappObject *self, PyObject *file)
2731/*[clinic end generated code: output=b53cc96ebf9476fd input=abbec19d66312e2a]*/
2732{
2733 int tfile;
Neal Norwitz12e22172003-03-03 21:16:39 +00002734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002735 CHECK_TCL_APPARTMENT;
Neal Norwitz12e22172003-03-03 21:16:39 +00002736
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002737 tfile = PyObject_AsFileDescriptor(file);
2738 if (tfile < 0)
2739 return NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00002740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002741 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00002742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002743 /* Ought to check for null Tcl_File object... */
2744 ENTER_TCL
2745 Tcl_DeleteFileHandler(tfile);
2746 LEAVE_TCL
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002747 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002748}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002749#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00002750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002751
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002752/**** Tktt Object (timer token) ****/
2753
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03002754static PyObject *Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002755
Guido van Rossum00d93061998-05-28 23:06:38 +00002756typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002757 PyObject_HEAD
2758 Tcl_TimerToken token;
2759 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002760} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002761
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002762/*[clinic input]
2763_tkinter.tktimertoken.deletetimerhandler
2764
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002765[clinic start generated code]*/
2766
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002767static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002768_tkinter_tktimertoken_deletetimerhandler_impl(TkttObject *self)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03002769/*[clinic end generated code: output=bd7fe17f328cfa55 input=40bd070ff85f5cf3]*/
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002770{
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002771 TkttObject *v = self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002772 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002774 if (v->token != NULL) {
2775 Tcl_DeleteTimerHandler(v->token);
2776 v->token = NULL;
2777 }
2778 if (func != NULL) {
2779 v->func = NULL;
2780 Py_DECREF(func);
2781 Py_DECREF(v); /* See Tktt_New() */
2782 }
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002783 Py_RETURN_NONE;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002784}
2785
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002786static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002787Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002789 TkttObject *v;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00002790
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03002791 v = PyObject_New(TkttObject, (PyTypeObject *) Tktt_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002792 if (v == NULL)
2793 return NULL;
Antoine Pitrou584e8152013-08-11 00:22:30 +02002794 Py_INCREF(Tktt_Type);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 Py_INCREF(func);
2797 v->token = NULL;
2798 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00002799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002800 /* Extra reference, deleted when called or when handler is deleted */
2801 Py_INCREF(v);
2802 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002803}
2804
2805static void
Fred Drake509d79a2000-07-08 04:04:38 +00002806Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002807{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002808 TkttObject *v = (TkttObject *)self;
2809 PyObject *func = v->func;
Antoine Pitrou584e8152013-08-11 00:22:30 +02002810 PyObject *tp = (PyObject *) Py_TYPE(self);
Guido van Rossum00d93061998-05-28 23:06:38 +00002811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002812 Py_XDECREF(func);
Guido van Rossum00d93061998-05-28 23:06:38 +00002813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002814 PyObject_Del(self);
Antoine Pitrou584e8152013-08-11 00:22:30 +02002815 Py_DECREF(tp);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002816}
2817
Guido van Rossum597ac201998-05-12 14:36:19 +00002818static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002819Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002820{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002821 TkttObject *v = (TkttObject *)self;
Victor Stinner6ced7c42011-03-21 18:15:42 +01002822 return PyUnicode_FromFormat("<tktimertoken at %p%s>",
2823 v,
2824 v->func == NULL ? ", handler deleted" : "");
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002825}
2826
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002827/** Timer Handler **/
2828
2829static void
Fred Drake509d79a2000-07-08 04:04:38 +00002830TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002832 TkttObject *v = (TkttObject *)clientData;
2833 PyObject *func = v->func;
2834 PyObject *res;
Guido van Rossum00d93061998-05-28 23:06:38 +00002835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002836 if (func == NULL)
2837 return;
Guido van Rossum00d93061998-05-28 23:06:38 +00002838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002839 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00002840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002841 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00002842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002843 res = PyEval_CallObject(func, NULL);
2844 Py_DECREF(func);
2845 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 if (res == NULL) {
2848 errorInCmd = 1;
2849 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2850 }
2851 else
2852 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00002853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002854 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002855}
2856
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002857/*[clinic input]
2858_tkinter.tkapp.createtimerhandler
2859
2860 milliseconds: int
2861 func: object
2862 /
2863
2864[clinic start generated code]*/
2865
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002866static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002867_tkinter_tkapp_createtimerhandler_impl(TkappObject *self, int milliseconds,
2868 PyObject *func)
2869/*[clinic end generated code: output=2da5959b9d031911 input=ba6729f32f0277a5]*/
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002870{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002871 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002873 if (!PyCallable_Check(func)) {
2874 PyErr_SetString(PyExc_TypeError, "bad argument list");
2875 return NULL;
2876 }
Martin v. Löwis7f134892003-03-03 10:40:01 +00002877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 CHECK_TCL_APPARTMENT;
Martin v. Löwis7f134892003-03-03 10:40:01 +00002879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002880 v = Tktt_New(func);
2881 if (v) {
2882 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2883 (ClientData)v);
2884 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002886 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002887}
2888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002889
Guido van Rossum18468821994-06-20 07:49:28 +00002890/** Event Loop **/
2891
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002892/*[clinic input]
2893_tkinter.tkapp.mainloop
2894
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002895 threshold: int = 0
2896 /
2897
2898[clinic start generated code]*/
2899
Guido van Rossum18468821994-06-20 07:49:28 +00002900static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002901_tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03002902/*[clinic end generated code: output=0ba8eabbe57841b0 input=036bcdcf03d5eca0]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002903{
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002904#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002905 PyThreadState *tstate = PyThreadState_Get();
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002906#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00002907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002908 CHECK_TCL_APPARTMENT;
2909 self->dispatching = 1;
Martin v. Löwisb5bfb9f2002-12-12 17:07:58 +00002910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002911 quitMainLoop = 0;
2912 while (Tk_GetNumMainWindows() > threshold &&
2913 !quitMainLoop &&
2914 !errorInCmd)
2915 {
2916 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00002917
2918#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002919 if (self->threaded) {
2920 /* Allow other Python threads to run. */
2921 ENTER_TCL
2922 result = Tcl_DoOneEvent(0);
2923 LEAVE_TCL
2924 }
2925 else {
2926 Py_BEGIN_ALLOW_THREADS
2927 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2928 tcl_tstate = tstate;
2929 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2930 tcl_tstate = NULL;
2931 if(tcl_lock)PyThread_release_lock(tcl_lock);
2932 if (result == 0)
2933 Sleep(Tkinter_busywaitinterval);
2934 Py_END_ALLOW_THREADS
2935 }
Guido van Rossum5b020781997-08-19 01:00:50 +00002936#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002937 result = Tcl_DoOneEvent(0);
Guido van Rossum5b020781997-08-19 01:00:50 +00002938#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002940 if (PyErr_CheckSignals() != 0) {
2941 self->dispatching = 0;
2942 return NULL;
2943 }
2944 if (result < 0)
2945 break;
2946 }
2947 self->dispatching = 0;
2948 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002950 if (errorInCmd) {
2951 errorInCmd = 0;
2952 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2953 excInCmd = valInCmd = trbInCmd = NULL;
2954 return NULL;
2955 }
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002956 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002957}
2958
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002959/*[clinic input]
2960_tkinter.tkapp.dooneevent
Guido van Rossum062cfb01995-01-10 17:42:51 +00002961
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002962 flags: int = 0
2963 /
2964
2965[clinic start generated code]*/
2966
2967static PyObject *
2968_tkinter_tkapp_dooneevent_impl(TkappObject *self, int flags)
2969/*[clinic end generated code: output=27c6b2aa464cac29 input=6542b928e364b793]*/
2970{
2971 int rv;
Barry Warsawfa701a81997-01-16 00:15:11 +00002972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002973 ENTER_TCL
2974 rv = Tcl_DoOneEvent(flags);
2975 LEAVE_TCL
Serhiy Storchaka8d0f6202015-05-06 14:19:22 +03002976 return PyLong_FromLong(rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00002977}
2978
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002979/*[clinic input]
2980_tkinter.tkapp.quit
2981[clinic start generated code]*/
2982
Guido van Rossum062cfb01995-01-10 17:42:51 +00002983static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002984_tkinter_tkapp_quit_impl(TkappObject *self)
2985/*[clinic end generated code: output=7f21eeff481f754f input=e03020dc38aff23c]*/
Guido van Rossum18468821994-06-20 07:49:28 +00002986{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002987 quitMainLoop = 1;
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03002988 Py_RETURN_NONE;
Guido van Rossum18468821994-06-20 07:49:28 +00002989}
2990
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002991/*[clinic input]
2992_tkinter.tkapp.interpaddr
2993[clinic start generated code]*/
2994
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002995static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03002996_tkinter_tkapp_interpaddr_impl(TkappObject *self)
2997/*[clinic end generated code: output=6caaae3273b3c95a input=2dd32cbddb55a111]*/
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002998{
Victor Stinnere1040e22013-09-05 00:22:24 +02002999 return PyLong_FromVoidPtr(Tkapp_Interp(self));
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00003000}
3001
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003002/*[clinic input]
3003_tkinter.tkapp.loadtk
3004[clinic start generated code]*/
3005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003006static PyObject *
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003007_tkinter_tkapp_loadtk_impl(TkappObject *self)
3008/*[clinic end generated code: output=e9e10a954ce46d2a input=b5e82afedd6354f0]*/
David Aschere2b4b322004-02-18 05:59:53 +00003009{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003010 Tcl_Interp *interp = Tkapp_Interp(self);
3011 const char * _tk_exists = NULL;
3012 int err;
David Aschere2b4b322004-02-18 05:59:53 +00003013
Guilherme Polob681df42009-02-09 22:33:59 +00003014#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003015 /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the
3016 * first call failed.
3017 * To avoid the deadlock, we just refuse the second call through
3018 * a static variable.
3019 */
3020 if (tk_load_failed) {
3021 PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG);
3022 return NULL;
3023 }
Guilherme Polob681df42009-02-09 22:33:59 +00003024#endif
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00003025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003026 /* We want to guard against calling Tk_Init() multiple times */
3027 CHECK_TCL_APPARTMENT;
3028 ENTER_TCL
3029 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
3030 ENTER_OVERLAP
3031 if (err == TCL_ERROR) {
3032 /* This sets an exception, but we cannot return right
3033 away because we need to exit the overlap first. */
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003034 Tkinter_Error((PyObject *)self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003035 } else {
3036 _tk_exists = Tkapp_Result(self);
3037 }
3038 LEAVE_OVERLAP_TCL
3039 if (err == TCL_ERROR) {
3040 return NULL;
3041 }
3042 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
3043 if (Tk_Init(interp) == TCL_ERROR) {
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +03003044 PyErr_SetString(Tkinter_TclError,
3045 Tcl_GetStringResult(Tkapp_Interp(self)));
Guilherme Polob681df42009-02-09 22:33:59 +00003046#ifdef TKINTER_PROTECT_LOADTK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003047 tk_load_failed = 1;
Guilherme Polob681df42009-02-09 22:33:59 +00003048#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003049 return NULL;
3050 }
3051 }
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03003052 Py_RETURN_NONE;
David Aschere2b4b322004-02-18 05:59:53 +00003053}
Barry Warsawfa701a81997-01-16 00:15:11 +00003054
Martin v. Löwisffad6332002-11-26 09:28:05 +00003055static PyObject *
3056Tkapp_WantObjects(PyObject *self, PyObject *args)
3057{
3058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003059 int wantobjects = -1;
3060 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
3061 return NULL;
3062 if (wantobjects == -1)
3063 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
3064 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003065
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03003066 Py_RETURN_NONE;
Martin v. Löwisffad6332002-11-26 09:28:05 +00003067}
3068
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003069/*[clinic input]
3070_tkinter.tkapp.willdispatch
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00003071
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003072[clinic start generated code]*/
3073
3074static PyObject *
3075_tkinter_tkapp_willdispatch_impl(TkappObject *self)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03003076/*[clinic end generated code: output=0e3f46d244642155 input=d88f5970843d6dab]*/
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003077{
3078 self->dispatching = 1;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00003079
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03003080 Py_RETURN_NONE;
Martin v. Löwis5b26abb2002-12-28 09:23:09 +00003081}
Martin v. Löwisffad6332002-11-26 09:28:05 +00003082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003083
Guido van Rossum18468821994-06-20 07:49:28 +00003084/**** Tkapp Type Methods ****/
3085
3086static void
Fred Drake509d79a2000-07-08 04:04:38 +00003087Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00003088{
Antoine Pitrou584e8152013-08-11 00:22:30 +02003089 PyObject *tp = (PyObject *) Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003090 /*CHECK_TCL_APPARTMENT;*/
3091 ENTER_TCL
3092 Tcl_DeleteInterp(Tkapp_Interp(self));
3093 LEAVE_TCL
3094 PyObject_Del(self);
Antoine Pitrou584e8152013-08-11 00:22:30 +02003095 Py_DECREF(tp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003096 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00003097}
3098
Barry Warsawfa701a81997-01-16 00:15:11 +00003099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003100
Guido van Rossum18468821994-06-20 07:49:28 +00003101/**** Tkinter Module ****/
3102
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003103typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003104 PyObject* tuple;
Serhiy Storchaka26861b02015-02-16 20:52:17 +02003105 Py_ssize_t size; /* current size */
3106 Py_ssize_t maxsize; /* allocated size */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003107} FlattenContext;
3108
3109static int
Serhiy Storchaka26861b02015-02-16 20:52:17 +02003110_bump(FlattenContext* context, Py_ssize_t size)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003111{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003112 /* expand tuple to hold (at least) size new items.
3113 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003114
Serhiy Storchaka26861b02015-02-16 20:52:17 +02003115 Py_ssize_t maxsize = context->maxsize * 2; /* never overflows */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003117 if (maxsize < context->size + size)
Serhiy Storchaka26861b02015-02-16 20:52:17 +02003118 maxsize = context->size + size; /* never overflows */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003120 context->maxsize = maxsize;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003123}
3124
3125static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00003126_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003127{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003128 /* add tuple or list to argument tuple (recursively) */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003129
Serhiy Storchaka26861b02015-02-16 20:52:17 +02003130 Py_ssize_t i, size;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003132 if (depth > 1000) {
3133 PyErr_SetString(PyExc_ValueError,
3134 "nesting too deep in _flatten");
3135 return 0;
Serhiy Storchaka2b00c492014-05-21 17:12:21 +03003136 } else if (PyTuple_Check(item) || PyList_Check(item)) {
3137 size = PySequence_Fast_GET_SIZE(item);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003138 /* preallocate (assume no nesting) */
3139 if (context->size + size > context->maxsize &&
3140 !_bump(context, size))
3141 return 0;
3142 /* copy items to output tuple */
3143 for (i = 0; i < size; i++) {
Serhiy Storchaka2b00c492014-05-21 17:12:21 +03003144 PyObject *o = PySequence_Fast_GET_ITEM(item, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003145 if (PyList_Check(o) || PyTuple_Check(o)) {
3146 if (!_flatten1(context, o, depth + 1))
3147 return 0;
3148 } else if (o != Py_None) {
3149 if (context->size + 1 > context->maxsize &&
3150 !_bump(context, 1))
3151 return 0;
3152 Py_INCREF(o);
3153 PyTuple_SET_ITEM(context->tuple,
3154 context->size++, o);
3155 }
3156 }
3157 } else {
3158 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
3159 return 0;
3160 }
3161 return 1;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003162}
3163
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003164/*[clinic input]
3165_tkinter._flatten
3166
3167 item: object
3168 /
3169
3170[clinic start generated code]*/
3171
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003172static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003173_tkinter__flatten(PyObject *module, PyObject *item)
3174/*[clinic end generated code: output=cad02a3f97f29862 input=6b9c12260aa1157f]*/
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003176 FlattenContext context;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003178 context.maxsize = PySequence_Size(item);
3179 if (context.maxsize < 0)
3180 return NULL;
3181 if (context.maxsize == 0)
3182 return PyTuple_New(0);
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00003183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003184 context.tuple = PyTuple_New(context.maxsize);
3185 if (!context.tuple)
3186 return NULL;
Guido van Rossum82c0dfa2007-11-21 20:09:18 +00003187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003188 context.size = 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003190 if (!_flatten1(&context, item,0))
3191 return NULL;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003193 if (_PyTuple_Resize(&context.tuple, context.size))
3194 return NULL;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003196 return context.tuple;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00003197}
3198
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003199/*[clinic input]
3200_tkinter.create
3201
Larry Hastingsdbfdc382015-05-04 06:59:46 -07003202 screenName: str(accept={str, NoneType}) = NULL
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003203 baseName: str = NULL
3204 className: str = "Tk"
3205 interactive: int(c_default="0") = False
3206 wantobjects: int(c_default="0") = False
3207 wantTk: int(c_default="1") = True
3208 if false, then Tk_Init() doesn't get called
3209 sync: int(c_default="0") = False
3210 if true, then pass -sync to wish
Larry Hastingsdbfdc382015-05-04 06:59:46 -07003211 use: str(accept={str, NoneType}) = NULL
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003212 if not None, then pass -use to wish
3213 /
3214
3215[clinic start generated code]*/
3216
Guido van Rossum18468821994-06-20 07:49:28 +00003217static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003218_tkinter_create_impl(PyObject *module, const char *screenName,
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003219 const char *baseName, const char *className,
3220 int interactive, int wantobjects, int wantTk, int sync,
3221 const char *use)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003222/*[clinic end generated code: output=e3315607648e6bb4 input=0d522aad1cb0ca0e]*/
Guido van Rossum18468821994-06-20 07:49:28 +00003223{
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003224 /* XXX baseName is not used anymore;
3225 * try getting rid of it. */
Serhiy Storchaka79851d72014-05-30 14:24:03 +03003226 CHECK_STRING_LENGTH(screenName);
3227 CHECK_STRING_LENGTH(baseName);
3228 CHECK_STRING_LENGTH(className);
3229 CHECK_STRING_LENGTH(use);
Guido van Rossum18468821994-06-20 07:49:28 +00003230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003231 return (PyObject *) Tkapp_New(screenName, className,
Andrew Svetlovd0ad0b32012-10-16 22:50:34 +03003232 interactive, wantobjects, wantTk,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003233 sync, use);
Guido van Rossum18468821994-06-20 07:49:28 +00003234}
3235
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003236/*[clinic input]
3237_tkinter.setbusywaitinterval
3238
3239 new_val: int
3240 /
3241
3242Set the busy-wait interval in milliseconds between successive calls to Tcl_DoOneEvent in a threaded Python interpreter.
3243
3244It should be set to a divisor of the maximum time between frames in an animation.
3245[clinic start generated code]*/
3246
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003247static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003248_tkinter_setbusywaitinterval_impl(PyObject *module, int new_val)
3249/*[clinic end generated code: output=42bf7757dc2d0ab6 input=deca1d6f9e6dae47]*/
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003250{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003251 if (new_val < 0) {
3252 PyErr_SetString(PyExc_ValueError,
3253 "busywaitinterval must be >= 0");
3254 return NULL;
3255 }
3256 Tkinter_busywaitinterval = new_val;
Andrew Svetlov9dc5bdd2012-10-07 12:08:38 +03003257 Py_RETURN_NONE;
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003258}
3259
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003260/*[clinic input]
3261_tkinter.getbusywaitinterval -> int
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003262
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003263Return the current busy-wait interval between successive calls to Tcl_DoOneEvent in a threaded Python interpreter.
3264[clinic start generated code]*/
3265
3266static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003267_tkinter_getbusywaitinterval_impl(PyObject *module)
3268/*[clinic end generated code: output=23b72d552001f5c7 input=a695878d2d576a84]*/
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003269{
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003270 return Tkinter_busywaitinterval;
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003271}
3272
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003273#include "clinic/_tkinter.c.h"
3274
3275static PyMethodDef Tktt_methods[] =
3276{
3277 _TKINTER_TKTIMERTOKEN_DELETETIMERHANDLER_METHODDEF
3278 {NULL, NULL}
3279};
3280
Larry Hastings2d0a69a2015-05-03 14:49:19 -07003281static PyType_Slot Tktt_Type_slots[] = {
3282 {Py_tp_dealloc, Tktt_Dealloc},
3283 {Py_tp_repr, Tktt_Repr},
3284 {Py_tp_methods, Tktt_methods},
3285 {0, 0}
3286};
3287
3288static PyType_Spec Tktt_Type_spec = {
3289 "_tkinter.tktimertoken",
3290 sizeof(TkttObject),
3291 0,
3292 Py_TPFLAGS_DEFAULT,
3293 Tktt_Type_slots,
3294};
3295
3296
3297/**** Tkapp Method List ****/
3298
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003299static PyMethodDef Tkapp_methods[] =
3300{
3301 _TKINTER_TKAPP_WILLDISPATCH_METHODDEF
3302 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
3303 {"call", Tkapp_Call, METH_VARARGS},
3304 _TKINTER_TKAPP_EVAL_METHODDEF
3305 _TKINTER_TKAPP_EVALFILE_METHODDEF
3306 _TKINTER_TKAPP_RECORD_METHODDEF
3307 _TKINTER_TKAPP_ADDERRINFO_METHODDEF
3308 {"setvar", Tkapp_SetVar, METH_VARARGS},
3309 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
3310 {"getvar", Tkapp_GetVar, METH_VARARGS},
3311 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
3312 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
3313 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
3314 _TKINTER_TKAPP_GETINT_METHODDEF
3315 _TKINTER_TKAPP_GETDOUBLE_METHODDEF
3316 _TKINTER_TKAPP_GETBOOLEAN_METHODDEF
3317 _TKINTER_TKAPP_EXPRSTRING_METHODDEF
3318 _TKINTER_TKAPP_EXPRLONG_METHODDEF
3319 _TKINTER_TKAPP_EXPRDOUBLE_METHODDEF
3320 _TKINTER_TKAPP_EXPRBOOLEAN_METHODDEF
3321 _TKINTER_TKAPP_SPLITLIST_METHODDEF
3322 _TKINTER_TKAPP_SPLIT_METHODDEF
3323 _TKINTER_TKAPP_CREATECOMMAND_METHODDEF
3324 _TKINTER_TKAPP_DELETECOMMAND_METHODDEF
3325 _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF
3326 _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF
3327 _TKINTER_TKAPP_CREATETIMERHANDLER_METHODDEF
3328 _TKINTER_TKAPP_MAINLOOP_METHODDEF
3329 _TKINTER_TKAPP_DOONEEVENT_METHODDEF
3330 _TKINTER_TKAPP_QUIT_METHODDEF
3331 _TKINTER_TKAPP_INTERPADDR_METHODDEF
3332 _TKINTER_TKAPP_LOADTK_METHODDEF
3333 {NULL, NULL}
3334};
Martin v. Löwis28e9ce92003-05-09 08:19:48 +00003335
Larry Hastings2d0a69a2015-05-03 14:49:19 -07003336static PyType_Slot Tkapp_Type_slots[] = {
3337 {Py_tp_dealloc, Tkapp_Dealloc},
3338 {Py_tp_methods, Tkapp_methods},
3339 {0, 0}
3340};
3341
3342
3343static PyType_Spec Tkapp_Type_spec = {
3344 "_tkinter.tkapp",
3345 sizeof(TkappObject),
3346 0,
3347 Py_TPFLAGS_DEFAULT,
3348 Tkapp_Type_slots,
3349};
3350
Guido van Rossum18468821994-06-20 07:49:28 +00003351static PyMethodDef moduleMethods[] =
3352{
Serhiy Storchaka5abdf4842015-05-03 15:49:47 +03003353 _TKINTER__FLATTEN_METHODDEF
3354 _TKINTER_CREATE_METHODDEF
3355 _TKINTER_SETBUSYWAITINTERVAL_METHODDEF
3356 _TKINTER_GETBUSYWAITINTERVAL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003357 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00003358};
3359
Guido van Rossum7bf15641998-05-22 18:28:17 +00003360#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00003361
3362static int stdin_ready = 0;
3363
Guido van Rossumad4db171998-06-13 13:56:28 +00003364#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00003365static void
Fred Drake509d79a2000-07-08 04:04:38 +00003366MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003368 stdin_ready = 1;
Guido van Rossum7bf15641998-05-22 18:28:17 +00003369}
Guido van Rossumad4db171998-06-13 13:56:28 +00003370#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003371
Martin v. Löwisa9656492003-03-30 08:44:58 +00003372#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00003373static PyThreadState *event_tstate = NULL;
Martin v. Löwisa9656492003-03-30 08:44:58 +00003374#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00003375
Guido van Rossum18468821994-06-20 07:49:28 +00003376static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003377EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003378{
Guido van Rossumad4db171998-06-13 13:56:28 +00003379#ifndef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003380 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00003381#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003382#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003383 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003384#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003385 stdin_ready = 0;
3386 errorInCmd = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00003387#ifndef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003388 tfile = fileno(stdin);
3389 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00003390#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003391 while (!errorInCmd && !stdin_ready) {
3392 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00003393#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003394 if (_kbhit()) {
3395 stdin_ready = 1;
3396 break;
3397 }
Guido van Rossumad4db171998-06-13 13:56:28 +00003398#endif
3399#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003400 Py_BEGIN_ALLOW_THREADS
3401 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
3402 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003404 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00003405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003406 tcl_tstate = NULL;
3407 if(tcl_lock)PyThread_release_lock(tcl_lock);
3408 if (result == 0)
3409 Sleep(Tkinter_busywaitinterval);
3410 Py_END_ALLOW_THREADS
Guido van Rossum00d93061998-05-28 23:06:38 +00003411#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003412 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00003413#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00003414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003415 if (result < 0)
3416 break;
3417 }
Guido van Rossumad4db171998-06-13 13:56:28 +00003418#ifndef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003419 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00003420#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003421 if (errorInCmd) {
3422 errorInCmd = 0;
3423 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3424 excInCmd = valInCmd = trbInCmd = NULL;
3425 PyErr_Print();
3426 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003427#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003428 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003429#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003430 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00003431}
Guido van Rossum18468821994-06-20 07:49:28 +00003432
Guido van Rossum00d93061998-05-28 23:06:38 +00003433#endif
3434
Guido van Rossum7bf15641998-05-22 18:28:17 +00003435static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003436EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003437{
Guido van Rossum00d93061998-05-28 23:06:38 +00003438#ifdef WAIT_FOR_STDIN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003439 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003440#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003441 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00003442#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003443 PyOS_InputHook = EventHook;
3444 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003445#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003446}
3447
3448static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003449DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00003450{
Guido van Rossum00d93061998-05-28 23:06:38 +00003451#ifdef WAIT_FOR_STDIN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003452 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3453 PyOS_InputHook = NULL;
3454 }
Guido van Rossum00d93061998-05-28 23:06:38 +00003455#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00003456}
3457
Barry Warsawfa701a81997-01-16 00:15:11 +00003458
Martin v. Löwis1a214512008-06-11 05:26:20 +00003459static struct PyModuleDef _tkintermodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003460 PyModuleDef_HEAD_INIT,
3461 "_tkinter",
3462 NULL,
3463 -1,
3464 moduleMethods,
3465 NULL,
3466 NULL,
3467 NULL,
3468 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00003469};
3470
Mark Hammond62b1ab12002-07-23 06:31:15 +00003471PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00003472PyInit__tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00003473{
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003474 PyObject *m, *uexe, *cexe, *o;
Guido van Rossum18468821994-06-20 07:49:28 +00003475
Guido van Rossum00d93061998-05-28 23:06:38 +00003476#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003477 tcl_lock = PyThread_allocate_lock();
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003478 if (tcl_lock == NULL)
3479 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00003480#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00003481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003482 m = PyModule_Create(&_tkintermodule);
3483 if (m == NULL)
3484 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00003485
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003486 o = PyErr_NewException("_tkinter.TclError", NULL, NULL);
3487 if (o == NULL) {
Jesus Ceaef86d122012-07-19 21:18:07 +02003488 Py_DECREF(m);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003489 return NULL;
Jesus Ceaef86d122012-07-19 21:18:07 +02003490 }
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003491 Py_INCREF(o);
3492 if (PyModule_AddObject(m, "TclError", o)) {
3493 Py_DECREF(o);
3494 Py_DECREF(m);
3495 return NULL;
3496 }
3497 Tkinter_TclError = o;
Guido van Rossum83551bf1997-09-13 00:44:23 +00003498
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003499 if (PyModule_AddIntConstant(m, "READABLE", TCL_READABLE)) {
3500 Py_DECREF(m);
3501 return NULL;
3502 }
3503 if (PyModule_AddIntConstant(m, "WRITABLE", TCL_WRITABLE)) {
3504 Py_DECREF(m);
3505 return NULL;
3506 }
3507 if (PyModule_AddIntConstant(m, "EXCEPTION", TCL_EXCEPTION)) {
3508 Py_DECREF(m);
3509 return NULL;
3510 }
3511 if (PyModule_AddIntConstant(m, "WINDOW_EVENTS", TCL_WINDOW_EVENTS)) {
3512 Py_DECREF(m);
3513 return NULL;
3514 }
3515 if (PyModule_AddIntConstant(m, "FILE_EVENTS", TCL_FILE_EVENTS)) {
3516 Py_DECREF(m);
3517 return NULL;
3518 }
3519 if (PyModule_AddIntConstant(m, "TIMER_EVENTS", TCL_TIMER_EVENTS)) {
3520 Py_DECREF(m);
3521 return NULL;
3522 }
3523 if (PyModule_AddIntConstant(m, "IDLE_EVENTS", TCL_IDLE_EVENTS)) {
3524 Py_DECREF(m);
3525 return NULL;
3526 }
3527 if (PyModule_AddIntConstant(m, "ALL_EVENTS", TCL_ALL_EVENTS)) {
3528 Py_DECREF(m);
3529 return NULL;
3530 }
3531 if (PyModule_AddIntConstant(m, "DONT_WAIT", TCL_DONT_WAIT)) {
3532 Py_DECREF(m);
3533 return NULL;
3534 }
3535 if (PyModule_AddStringConstant(m, "TK_VERSION", TK_VERSION)) {
3536 Py_DECREF(m);
3537 return NULL;
3538 }
3539 if (PyModule_AddStringConstant(m, "TCL_VERSION", TCL_VERSION)) {
3540 Py_DECREF(m);
3541 return NULL;
3542 }
3543
3544 o = PyType_FromSpec(&Tkapp_Type_spec);
3545 if (o == NULL) {
3546 Py_DECREF(m);
3547 return NULL;
3548 }
Serhiy Storchakae3f1b092016-05-08 20:46:22 +03003549 ((PyTypeObject *)o)->tp_new = NULL;
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003550 if (PyModule_AddObject(m, "TkappType", o)) {
3551 Py_DECREF(o);
3552 Py_DECREF(m);
3553 return NULL;
3554 }
3555 Tkapp_Type = o;
3556
3557 o = PyType_FromSpec(&Tktt_Type_spec);
3558 if (o == NULL) {
3559 Py_DECREF(m);
3560 return NULL;
3561 }
Serhiy Storchakae3f1b092016-05-08 20:46:22 +03003562 ((PyTypeObject *)o)->tp_new = NULL;
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003563 if (PyModule_AddObject(m, "TkttType", o)) {
3564 Py_DECREF(o);
3565 Py_DECREF(m);
3566 return NULL;
3567 }
3568 Tktt_Type = o;
3569
3570 o = PyType_FromSpec(&PyTclObject_Type_spec);
3571 if (o == NULL) {
3572 Py_DECREF(m);
3573 return NULL;
3574 }
Serhiy Storchakae3f1b092016-05-08 20:46:22 +03003575 ((PyTypeObject *)o)->tp_new = NULL;
Andrew Svetlov11dc6c32012-10-14 16:54:35 +03003576 if (PyModule_AddObject(m, "Tcl_Obj", o)) {
3577 Py_DECREF(o);
3578 Py_DECREF(m);
3579 return NULL;
3580 }
3581 PyTclObject_Type = o;
Jack Jansencb852442001-12-09 23:15:56 +00003582
3583#ifdef TK_AQUA
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003584 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3585 * start waking up. Note that Tcl_FindExecutable will do this, this
3586 * code must be above it! The original warning from
3587 * tkMacOSXAppInit.c is copied below.
3588 *
3589 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3590 * Tcl interpreter for now. It probably should work to do this
3591 * in the other order, but for now it doesn't seem to.
3592 *
3593 */
3594 Tk_MacOSXSetupTkNotifier();
Jack Jansencb852442001-12-09 23:15:56 +00003595#endif
3596
3597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003598 /* This helps the dynamic loader; in Unicode aware Tcl versions
3599 it also helps Tcl find its encodings. */
3600 uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1);
3601 if (uexe) {
Victor Stinnerae6265f2010-05-15 16:27:27 +00003602 cexe = PyUnicode_EncodeFSDefault(uexe);
Zachary Ware7dc9dea2015-05-22 11:36:53 -05003603 if (cexe) {
3604#ifdef MS_WINDOWS
3605 int set_var = 0;
3606 PyObject *str_path;
3607 wchar_t *wcs_path;
3608 DWORD ret;
3609
3610 ret = GetEnvironmentVariableW(L"TCL_LIBRARY", NULL, 0);
3611
3612 if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
3613 str_path = _get_tcl_lib_path();
3614 if (str_path == NULL && PyErr_Occurred()) {
3615 return NULL;
3616 }
3617 if (str_path != NULL) {
3618 wcs_path = PyUnicode_AsWideCharString(str_path, NULL);
3619 if (wcs_path == NULL) {
3620 return NULL;
3621 }
3622 SetEnvironmentVariableW(L"TCL_LIBRARY", wcs_path);
3623 set_var = 1;
3624 }
3625 }
3626
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03003627 Tcl_FindExecutable(PyBytes_AS_STRING(cexe));
Zachary Ware7dc9dea2015-05-22 11:36:53 -05003628
3629 if (set_var) {
3630 SetEnvironmentVariableW(L"TCL_LIBRARY", NULL);
3631 PyMem_Free(wcs_path);
3632 }
3633#else
Serhiy Storchaka696c8af2016-06-19 11:22:47 +03003634 Tcl_FindExecutable(PyBytes_AS_STRING(cexe));
Zachary Ware7dc9dea2015-05-22 11:36:53 -05003635#endif /* MS_WINDOWS */
3636 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003637 Py_XDECREF(cexe);
3638 Py_DECREF(uexe);
3639 }
Guido van Rossume187b0e2000-03-27 21:46:29 +00003640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003641 if (PyErr_Occurred()) {
3642 Py_DECREF(m);
3643 return NULL;
3644 }
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00003645
Guido van Rossum43ff8681998-07-14 18:02:13 +00003646#if 0
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003647 /* This was not a good idea; through <Destroy> bindings,
3648 Tcl_Finalize() may invoke Python code but at that point the
3649 interpreter and thread state have already been destroyed! */
3650 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00003651#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003652 return m;
Guido van Rossum18468821994-06-20 07:49:28 +00003653}